flex布局基础知识整理

建议大家看完阮一峰老师的Flex 布局教程:语法篇再看这篇文章;另:本文中的思维导图使用新建标签页的方式打开才能看的清楚。

一、使用flex布局注意事项

使用flex后,子元素的clear 、float(使用 float 将使元素的 display 属性计为block。)、vertical-align及多栏布局模块的column-*均会失效;

二、flex布局的兼容性

Paste_Image.png

三、块级元素及行内元素flex布局用法

对于块级元素可直接使用display:flex,(当然你也可以用display:inline-flex,注意他们的区别即可)对于行内元素可使用display:inline-flex;

四、flex布局基本概念

元素采用了flex布局,则该元素称为容器(flex container),其所有子元素称为项目(flex item);容器默认存在两个轴---横向的主轴main,纵向的交叉轴cross,主轴开始的地方叫做main start(与边框的交叉点),结束的地方叫main end,单个项目占据主轴的空间称为main size,同理,交叉轴开始的地方叫做cross start 结束的地方叫做 cross end,单个项目占据交叉轴的空间叫做cross size;项目默认沿主轴排列。

五、容器的6大属性

flex布局容器的6大属性.png

1、 align-items属性补充点
1、使用align-items:stretch 属性时必须将每一块的高度指定为auto,否则高度属性(height)就会将stretch作用的属性给覆盖掉;
2、对于使用align-items: baseline来说,如果元素标签内无文字或其子标签内无文字,均会按照每个块的底部对齐;如下图:

无文字align-items: baseline

2、flex-direction 属性补充点
a、使用row-reverse或者column-reverse后,flex-end及flex-start对应的方向也被调转了。这是在做 青蛙游戏的第十关发现的。。。。
b、同样的道理,当flex-direction的值为column时,justify-content变成了控制竖直方向而align-content变成了控制水平方向了。

六、项目的6大属性

flex布局项目的6大属性.png

** (一)、flex属性补充点**:

  • 1、flex:非负数字, 这种写法表示的是
flex-grow:非负数字;
flex-shrink: 1;
 flex-basis: 0%;
  • 2、flex:auto 这种写法表示的是
flex-grow:1;
flex-shrink: 1;
 flex-basis: auto;
  • 3、flex:长度或百分比
    这种写法表示的是
flex-grow:1;
flex-shrink: 1;
 flex-basis: 长度或百分比;
  • 4、flex: 非负数字 非负数字 这种写法表示的是
flex-grow:非负数字;
flex-shrink: 非负数字;
 flex-basis: 0%;
  • 5、flex:非负数字 长度或百分比 这种写法表示的是
flex-grow:非负数字;
flex-shrink: 1;
 flex-basis: 长度或百分比;

** (二)、flex-basis属性补充点**:

Paste_Image.png

我将第二个div的flex-basis设置成了100%,它的宽度就变成了350px,与容器的宽度相等;

  • 2、对于flex-basis更深一步的理解

<style type="text/css">
    .parent {
        display: flex;
        width: 600px;
    }
    .parent > div {
        height: 100px;
    }
    .item-1 {
        width: 140px;
        flex: 2 1 0%;
        background: blue;
    }
    .item-2 {
        width: 100px;
        flex: 2 1 auto;
        background: darkblue;
    }
    .item-3 {
        flex: 1 1 200px;
        background: lightblue;
    }
</style>
<div class="parent">
    <div class="item-1"></div>
    <div class="item-2"></div>
    <div class="item-3"></div>
</div>

在线版http://output.jsbin.com/xowihaweti
上述代码浏览器解析后,item-1、item-2、item-3的宽度分别为120px,220px,260px;那么浏览器是怎么计算的呢?

a、首先我们来看下剩余空间的计算:剩余空间=600px(容器的宽度)- 0px(0px为 item-1的基准空间 即flex属性中的0%)- 100px(item-2的基准空间 即flex属性中的auto及width:100px)- 200px(item-3的基准空间 即flex属性中的200px)= 300px
b、剩余空间的分布:由于有剩余空间且flex-shrink均为1,因此我们看下他们的flex-grow--- item-1、item-2、item-3分别为2,2,1;因此item-1和item-2各占了2/5, item-3 占了1/5;因此item-1及item-2的增长幅度均为300 乘以 2/5 为 120px,item-3的增长幅度为300乘以1/5为60px;
c、综上所述, item-1的宽度为0px+120px=120px, item-2的宽度为100px+120px=220px, item-3的宽度为200px+60px=260px;

上面我们可以看到 虽然 item-1 声明了 width: 140px ,但是由于 flex: 2 1 0% 的存在,width: 140px这条语句是无效的。不信,我们可以随意改下这个数值,发现并无任何变化。(如果同时设置flex-basis和width,那么width属性会被覆盖,也就是说flex-basis的优先级比width高。有一点需要注意,如果flex-basis和width其中有一个是auto,那么另外一个非auto的属性优先级会更高。)其实通过这个例子,我们还可以知道flex:auto与flex:1并不是等价的! (flex:auto是flex-grow:1;flex-shrink:1;flex-basis:auto;的简写,flex:1是flex-grow:1;flex-shrink:1;flex-basis:0%的简写;)
关于flex-basis的详细介绍可参考w3c官网:猛戳此处

w3c官网介绍flex-basis

在看阮一峰老师的博客flex布局中的圣杯布局部分,当时看到

.HolyGrail {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

header,
footer {
  flex: 1;
}

.HolyGrail-body {
  display: flex;
  flex: 1;
}

.HolyGrail-content {
  flex: 1;
}

.HolyGrail-nav, .HolyGrail-ads {
  /* 两个边栏的宽度设为12em */
  flex: 0 0 12em;
}

.HolyGrail-nav {
  /* 导航放到最左边 */
  order: -1;
}

中的flex:1 不是很理解,为什么不用flex:auto。现在看这个w3c的文档就很容易理解为什么了。(flex:1等同于flex:1,1,0%,而flex:auto等同于flex:1,1,auto;)

  • 3、关于flex-shrink的理解,可以看下面的代码:
<style>
.container {
    display: -webkit-flex;
    display: flex;
    width: 500px;
    height: 150px;
    background-color: #eee;
}
.B {
    height: 100px;
}
.B1{
    background-color:rgba(255,255,0,.5);
    width: 300px;
    -webkit-flex-grow:1;
    -moz-flex-grow:1;
    flex-grow:1;
    -webkit-flex-shrink:2;
    -moz-flex-shrink:2;
    flex-shrink:2;
}
.B2{
    background-color:rgba(255,0,255,.5);
    width: 160px;
}
.B3{
    background-color:rgba(0,255,255,.5);
    width: 120px;
}
</style>
<div class="container">
    <div class="B B1">width:300</div>
    <div class="B B2">width:160</div>
    <div class="B B3">width:120</div>
</div>

假设B2,B3被缩小了s1(压缩率),则B1被缩小了s2(压缩率);
那么存在 s2=2*s1; 500=300*s2+160*s1+120*s1;

顺便提下,在查资料时,发现了MDN上有一个错误:https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex

Paste_Image.png

但是单独介绍flex-grow的页面又是正确的:

Paste_Image.png

七、测试flex各个属性网站推荐

http://the-echoplex.net/flexyboxes/

可以在该网页的右侧选择flex相应参数,直接查看各个元素的变化。

Paste_Image.png

八、flex布局练习--骰子篇(练习flex容器)

可以好好看下阮一峰的这篇文章,试着自己先写完再看他的答案。下面我总结下自已看这个应该注意的几点:

  • 1、刚开始的时候我差点把align-items和justify-content搞错了。。。
justify-content
align-items

其实记忆起来很简单,在flex-direction为row或者row-reverse时,justify-content是管水平方向的,而align-items是管竖直方向的;可以看下面的图理解下:

justify-content示意图
align-items示意图
  • 2、flex-direction:column 会将主轴的水平方向变成垂直方向,如下图:
Paste_Image.png

因此,


Paste_Image.png

这个图的正确写法是:

.box{
display:flex;
flex-direction:column;
justify-content:between;
align-items:center;
}

同理:

Paste_Image.png

这个图的写法是:

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
}

也就是说使用flex-direction,使得主轴的方向由水平变成了竖直方向,交叉轴的方向由竖直方向变成了水平方向;

  • 3、对于有多轴情况的,我们应该想到align-content,例如下面的图:
Paste_Image.png

这个图的写法是:

.box{
flex-wrap:wrap;
justify-content:flex-end;
align-content:space-between;
}
  • 4、对于某些情况需要使用flex-basis的,记得使用;
    比如:
    Paste_Image.png

HTML代码:

<div class="box">
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
  <div class="column">
    <span class="item"></span>
    <span class="item"></span>
  </div>
</div>

CSS代码:

.box{
display:flex;
flex-wrap:wrap;
align-content:space-between;
}
.column{
display:flex;
flex-basis:100%;
justify-content:space-between;
}

九、flex布局练习--游戏篇

1、青蛙游戏 http://flexboxfroggy.com/#zh-cn

通关

2、 塔防游戏 http://www.flexboxdefense.com/

通关

十、其他布局的补充

除了flex布局还有网格布局及多列布局:

1、网格布局 CSS Grid Layout

关于它与flex的对比,可参考grid layout 和其它布局方法的联系
Hold住CSS布局新属性 。里面都提到flex只是一维布局(沿横向或纵向),而CSS Grid Layout属于二维布局(同时沿横向和纵向);也就是说如果我们只想单独控制行或者列时,我们可以考虑使用flex布局,如果我们想要同时同时行和列时,我们可以考虑使用网格布局。还有一种方法来决定我们是使用弹性盒还是网格布局就是:弹性盒布局是从内容出发的,而网格布局是从布局出发的。值得一提的是网格布局的兼容性目前相对弹性盒布局来说不是很好,见下图:

Paste_Image.png

2、多列布局 CSS3 Multiple column layout

它的兼容性见下图:

Paste_Image.png

**本文版权归本人即简书笔名:该账户已被查封 所有,如需转载请注明出处。谢谢! *

推荐阅读更多精彩内容

  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 1,870评论 0 24
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 1,554评论 0 5
  • 前言 FlexBox是css3的一种新的布局方式,天生为解决布局问题而存在的它,比起传统的布局方式,我们使用Fle...
    zevei阅读 437评论 0 3
  • 网页布局(layout)是CSS的一个重点应用。 一、Flex布局是什么? Flex是Flexible Box的缩...
    抱着熊喵啃什么阅读 323评论 0 4
  • 我心爱的物品: 我的包包——带紫色毛的 黑色双肩的 我的mini裙—— 坎袖的 胸前透明蕾丝边的 条纹的 我的鞋子...
    54一片云阅读 26评论 0 1