Flex弹性布局详解
前言:
flex就是flexible box的缩写,意为弹性布局,任何一个容器都可以指定为flex布局
Webkit内核的浏览器,必须加上-webkit前缀。
1 | .box{ |
注意:设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。
🌀Flex布局与传统布局对比:
传统布局:
- 兼容性好
- 布局繁琐
- 局限(不能在移动端很好的布局)
FLex布局:
- 操作方便,布局简单,移动端广泛应用
- PC端浏览器支持较差
- IE11或更低版本不支持或部分支持
🌀Flex布局原理:
–通过给父元素添加flex属性来控制子元素的位置和排列方式
基本概念
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start
,结束位置叫做main end
;交叉轴的开始位置叫做cross start
,结束位置叫做cross end
项目默认沿主轴排列,单个项目占据的主轴空间叫做main size
,占据的交叉轴空间叫做cross size
容器属性
- flex-direction:设置主轴方向,一般默认为x轴
- justify-content:设置主轴上的子元素排列方式,一般默认为y轴
- flex-wrap:设置子元素是否换行
- align-items:设置侧轴上子元素排列方式(单行)
- align-content:设置侧轴上子元素排列方式(多行)
- align-self:控制子元素本身在交叉轴上的对齐方式
- flex-flow:复合属性,同时设置了flex-direction和flex-wrap
flex-direction属性
flex-direction
属性决定主轴的方向(即项目的排列方向)。
1 | .box { |
属性值:
row
:默认值,主轴为水平方向,起点在左端。row-reverse
:主轴为水平方向,起点在右端。column
:主轴为垂直方向,起点在上沿。column-reverse
:主轴为垂直方向,起点在下沿
1 | <body> |
justify-content属性
justify-content
是用于控制项目在主轴上的对齐方式。常用属性有以下六个
1 | .box { |
属性值:
flex-start
:默认值,子盒子在主轴方向上排列,一般是在x轴水平方向,从左到右。flex-end
:子盒子在主轴方向上反向排列,一般是在x轴水平方向,从右到左边。center
:子盒子在主轴方向上居中。space-between
:子盒子在主轴方向上,两端对齐,然后项目中间间隔是相等的。space-around
:在主轴方向上,在左右两侧会留下边距。space-evenly
:均匀排列每个元素,每个元素之间的间隔相等
space-around、space-evenly和space-between的区别
flex-wrap属性
- flex-wrap: 控制项目(子元素)是否换行
它可能取三个值:
- nowrap:(默认值)不换行;
- wrap:换行,第一行在上方;
- wrap-reverse:换行,第一行在下方。
注意:默认情况下是不换行的,如果父元素装不下会缩小所有子元素的宽度,使子元素挤在一起。
如下
1 | <body> |
- 这里我父盒子长度设为300px,每个子盒子长度设为100px,此时不设置flex-wrap:wrap,会发生什么情况呢?
- 没错,不会换行,子盒子的宽度100px失效了,会自适应父盒子的宽度,主要是根据原本的宽度大小来进行等比缩放
- 如图
- 那么如果设置了flex-wrap:wrap,超出的部分就会进行分行
- 如图
align-items属性
align-items
是控制项目在交叉轴上的对齐方式,一般是垂直方向y轴上面的。- 有常用的五个属性
1 | .box { |
stretch
:默认值,如果项目没有设置固定高度,则会被拉伸填充满交叉轴方向剩余的空间。flex-start
:项目在沿交叉轴起始线位置对齐。flex-end
:项目沿交叉轴终点线位置对齐。center
:项目在交叉轴方向居中对齐。baseline
:项目在交叉轴方向沿项目中第一行文字的基线对齐。
- stretch 是“拉伸,拉长”的意思,所以项目会被拉伸
- start、end、center 分别的“起始”、“终点”、“中间”的意思,所以项目分别是起始位置、终端位置、居中对齐。
- baseline 是“基线、底线”的意思,这里是沿文字的基线对齐的意思。
align-content属性
align-content
控制多行项目(多根主轴线)对齐方式。类似justify-content
,只不过,align-content
是控制行与行之间的空间分配,justify-content
是控制子盒子与子盒子之间的空间分配。- 有七个常用的属性
1 | .box { |
- 除了stretch属性外,其他的属性功能和性质基本和justify-content那里的属性一样
stretch
:默认值,交叉轴方向剩余的空间平均分配到每一行,并且行的高度会拉伸,填满整行的空间
align-self属性
align-self
控制子盒子本身在交叉轴上的对齐方式。优先级高于align-items
。align-items
是容器统一控制容器里的每个子盒子的对齐方式,align-self
则是子盒子控制子盒子本身的对齐方式。
1 | .item-box { |
- 默认值:
align-self: auto;
,继承容器设置的align-items
的值。也就是默认是由容器设置align-items
统一控制项目在交叉轴上的对齐方式。 - 除了比
align-items
多一个auto
选项外,其他选项与align-items
一致。
1 | .container { |
flow-grow属性
flex-grow
用于控制子盒子在主轴方向上拉伸放大占剩余空间(如果有的话)的比例。- grow 的意思是“扩大,使生长”,所以就是让项目放大的意思。
1 | .item-box { |
- 默认值:
0
,不放大。
例子中,容器宽设为 300px,项目宽设为 50px。项目总宽 150px,剩余空间宽 150px
flex-grow 都设置为 1 的时候,项目拉伸成 100px,剩余空间被按 1:1:1 分配,每个项目各占了 1/3。
flex-grow 分别设为 33、66、66 的时候,项目分别被拉伸成 87.5px、125px、87.5px,剩余空间被按 1:2:1 分配,项目分别占了剩余空间的 1/4、1/2、1/4。
可以看到,放大的比例跟数值的大小无关,跟数值的比例有关。
flow-shrink属性
flex-shrink
用于控制项目在主轴方向上缩小的程度。数值越大,收缩越多
1 | .item-box { |
- 默认是
flex-shrink: 1
,同等比例收缩。
例子中,容器宽为 400px,项目宽为100px。因为项目超过了容器空间,所以自动被缩小了。默认 flex-shrink 是 1,所有项目同等比例缩小成 80px。
右上,设置 flex-shrink,全部设置为 0,项目保存原来设置的宽度 100px,不缩小,所以溢出容器空间。
右中,设置 flex-shrink 分别为 6、6、6、默认、默认,项目宽变成 70px、70px、70px、95px、95px,超出的 100px 分成 20 份,按比例缩小。
右上,设置 flex-shrink 分别为 999、默认、默认、默认、默认,项目宽变成 16px、96px、96px、96px、96px,可以看到这里就不按比例缩小的了。
flex-basis属性
flex-basis
用于初始化每个项目占据主轴空间的尺寸(main size)
1 | .item-box { |
- 默认值:
flex-basis: auto
, 自动检测尺寸,如果项目有设置尺寸,则取项目设置的值,否则根据项目内容计算出尺寸。
flex 项目的属性:flex
flex
是上面三个合并的简写。
1 | .item { |
- 默认值:
flex: 0 1 auto;
后两个参数为可选参数。
flex: auto
:等同于flex: 1 1 auto
。可以拉伸,可以缩小,自动计算项目尺寸,一般情况下会自动拉伸填充满整个容器。flex: none
: 等同于flex: 0 0 auto
。不能拉伸,不能缩小,直接使用获取到项目的flex-basis
尺寸。flex: <positive-number>
:等同于flex: <positive-number> 1 0
。positive-number 为正数,例如flex: 1
等同于flex: 1 1 0
。
flex 项目的属性:order
order
用于控制项目在主轴上的排列顺序。
1 | .item-box { |
- 默认值:
order: 0;
,参数值正负数都可以,全部项目按主轴方向依次排列。设置后,按数值大小,从小到大排列。