简介
Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。
我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。
基本概念
Flex布局是一个完整的模块而不是一个单独的属性,它包括了完整的一套属性。其中有的属性是设置在容器(container,也可以叫做父元素,称为flex container)上,有的则是设置在容器的项目上(item,也可以叫做子元素,称为flex items)上。
轴线
当使用 flex 布局时,首先想到的是两根轴线 — 主轴和交叉轴。主轴由 flex-direction
定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关, 所以有必要在一开始首先理解它。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
Flex容器
我们把一个容器的 display
属性值改为 flex
或者 inline-flex。
完成这一步之后,容器中的直系子元素就会变为 flex 元素。所有CSS属性都会有一个初始值,所以 flex 容器中的所有 flex 元素都会有下列行为:
- 元素排列为一行 (
flex-direction
属性的初始值是row
)。 - 元素从主轴的起始线开始。
- 元素不会在主维度方向拉伸,但是可以缩小。
- 元素被拉伸来填充交叉轴大小。
-
flex-basis
属性为auto。
-
flex-wrap
属性为nowrap。
这会让你的元素呈线形排列,并且把自己的大小作为主轴上的大小。如果有太多元素超出容器,它们会溢出而不会换行。如果一些元素比其他元素高,那么元素会沿交叉轴被拉伸来填满它的大小。
容器属性
1. flex-direction
决定主轴的方向(即项目的排列方向),有四个值。
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
row(默认值):主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column:主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
2.flex-wrap
默认情况下,flex布局中父元素会把子元素尽可能地排在同一行,通过设置flex-wrap来决定是否允许子元素这行排列。
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap: 不折行,默认值,所有的子元素会排在一行。
wrap: 折行,子元素会从上到下根据需求折成多行。
wrap-reverse: 从下向上折行,子元素会从下到上根据需求折成多行。
3.flex-flow
flex-flow是flex-direction和flex-wrap属性的缩写形式。默认值是row,nowrap。
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
4.justify-content
justify-content属性定义了子元素沿主轴方向的对齐方式,用来当子元素大小最大的时候,分配主轴上的剩余空间。也可以当子元素超出主轴的时候用来控制子元素的对齐方式。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
- flex-start: 默认值,朝主轴开始的方向对齐。
- flex-end: 朝主轴结束的方向对齐。
- center: 沿主轴方向居中。
- space-between: 沿主轴两端对齐,第一个子元素在主轴起点,最后一个子元素在主轴终点。
- space-around: 沿主轴子元素之间均匀分布。要注意的是子元素看起来间隙是不均匀的,第一个子元素和最后一个子元素离父元素的边缘有一个单位的间隙,但两个子元素之间有两个单位的间隙,因为每个子元素的两侧都有一个单位的间隙。
5.align-items
align-items定义了子元素在交叉轴方向的对齐方向,这是在每个子元素仍然在其原来所在行的基础上所说的。可以看作是交叉轴上的justify-content属性;
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
- flex-start: 按照交叉轴的起点对齐。
- flex-end: 按照交叉轴的终点对齐。
- center: 沿交叉轴方向居中。
- baseline: 按照项目的第一行文字的基线对齐。
- stretch: 默认值,在满足子项目所设置的min-height、max-height、height的情况下拉伸子元素使之填充整个父元素。
6.align-content
align-content是当父元素所包含的行在交叉轴方向有空余部分时如何分配空间。与justify-content在主轴上如何对单个子元素对齐很相似。
注意:当只有一行的时候,该属性并不起作用。
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
注意align-items和align-content的区别,前者是指在单行内的子元素对齐方式,后者是指多行之间的对齐方式。
flex 元素
为了更好地控制 flex 元素,有三个属性可以作用于它们:
flex 元素属性
1.order
默认情况下,子元素按照代码书写的先后顺序布局,但order属性可以更改子元素出现的顺序。
.item {
order: <integer>;
}
order的默认值为0;子元素的order值越小,布局越排在前面,参考例图理解。
2.flex-grow
定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。如果所有的子元素的属性都设定为1,则父元素中的剩余空间会等分给所有子元素。如果其中某个子元素的flex-grow设定为2,则在分配剩余空间时该子元素将获得其他元素二倍的空间(至少会尽力获得)。
.item {
flex-grow: <number>; /* default 0 */
}
3.flex-shrink
与flex-grow属性类似,flex-shrink定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item {
flex-shrink: <number>; /* default 1 */
}
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。
4.flex-basis
设置或检索弹性盒伸缩基准值,如果所有子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间
.item {
flex-basis: <length> | auto; /* default auto */
}
5.flex
flex是flex-grow、flex-shrink、flex-basis三个属性的缩写。其中第二个和第三个参数(flex-grow,flex-basis)是可选的。默认值为0 1 auto。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
推荐使用缩写形式而不是单独地设置每一个属性,缩写形式中会智能地计算出相关值
6.align-self
通过设置某个子元素的align-self属性,可以覆盖align-items所设置的对齐方式。属性值与align-items中的意义相同,不再赘述。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
注:float,clear和vertical-align对flex子元素没有任何影响。
参考
MDN
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
https://segmentfault.com/a/1190000008823763
https://zhuanlan.zhihu.com/p/25303493
网友评论