简单介绍
- Flexible Box 模型,通常被称为 flexbox,是CSS3中新出现一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。
- 我们说 flexbox 是一种一维的布局,是因为一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 grid布局,可以同时处理行和列上的布局。
- 一般来说:flexbox布局适合应用程序的组件和小规模布局,而grid布局则适用于更大规模的布局
flex容器及容器上的属性
文档中采用了 flexbox 的区域就叫做 flex 容器。为了创建 flex 容器, 我们把一个容器的 display
属性值改为 flex
或者 inline-flex。
完成这一步之后,容器中的直系子元素就会变为 flex 元素。所有CSS属性都会有一个初始值,所以 flex 容器中的所有 flex 元素都会有下列行为:
- 元素排列为一行 (
flex-direction
属性的初始值是row
)。
元素从主轴的起始线开始。
元素不会在主维度方向拉伸,但是可以缩小。
元素被拉伸来填充交叉轴大小。
-
flex-direction:row |row-reverse |column |column-reverse
限定子元素排布方向,如下图
-
flex-wrap:nowrap| wrap |wrap-reverse
限定子元素是否换行,如下图
flex-flow:
是flex-direction和flex-wrap
的合并写法-
justify-content:flex-start|flex-end|center|space-around|space-between
控制子元素在水平方向上的位置,如下图
-
align-items:flex-start|flex-end|center|stretch|baseline
控制子元素在垂直方向上位置,如下图
-
align-content:flex-start | flex-end | center | space-between | space-around | stretch;
控制子元素整体在容器内的位置,如下图
flex 元素上的属性
-
order
控制子元素的呈现顺序
为了更好地控制 flex 元素,还有三个属性可以作用于它们
-
flex-grow
用于瓜分父项的剩余空间 -
flex-shrink
用以吸收超出的空间 -
flex-basis
用于设置子项的占用空间,基准宽度
- 在考虑这几个属性的作用之前,需要先了解一下 布局空白 available space 这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的布局空白的行为。同时,布局空白对于 flex 元素的对齐行为也是很重要的。
-
假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的布局空白。在默认情况下, flexbox 的行为会把这 200px 的空白留在最后一个元素的后面。
- 如果期望这些元素能自动地扩展去填充满剩下的空白,那么我们需要去控制布局空白在这几个元素间如何分配,这就是元素上的那些
flex
属性要做的事。
Flex 元素属性:flex-basis
-
flex-basis
定义了该元素的布局空白(available space)的基准值。 该属性的默认值是auto
。此时,浏览器会检测这个元素是否具有确定的尺寸。 在上面的例子中, 所有元素都设定了宽度(width)为100px,所以flex-basis
的值为100px。 - flex-basis 用于设置子项的占用空间。如果设置了值,则子项占用的空间为设置的值;如果没设置或者为 auto,那子项的空间为width/height 的值。
举个例子
- 对于子项1,flex-basis 如果设置默认是auto,子项占用的宽度使用width 的宽度,width没设置也为 auto,所以子项占用空间由内容决定。
- 对于子项2,flex-basis 为auto,子项占用宽度使用width 的宽度,width 为70px,所以子项子项占用空间是70px。
- 对于子项3,flex-basis 为100px,覆盖width 的宽度,所以子项占用空间是100px。
- 如果没有给元素设定尺寸,
flex-basis
的值采用元素内容的尺寸。这就解释了:我们给只要给Flex元素的父元素声明display: flex
,所有子元素就会排成一行,且自动分配小大以充分展示元素的内容。
Flex 元素属性:flex-grow
-
flex-grow
若被赋值为一个正整数, flex 元素会以flex-basis
为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的布局空白(available space)。如果有其他元素也被允许延展,那么他们会各自占据布局空白的一部分。 - 如果我们给上例中的所有元素设定
flex-grow
值为1, 容器中的布局空白会被这些元素平分。它们会延展以填满容器主轴方向上的空间。 - flex-grow 属性可以按比例分配空间。如果第一个元素
flex-grow
值为2, 其他元素值为1,则第一个元素将占有2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有1/4(各50px)。
举个例子
- 容器的宽度为400px, 子项1的占用的基础空间(flex-basis)为50px,子项2占用的基础空间是70px,子项3占用基础空间是100px,剩余空间为 400-50-70-100 = 180px。 其中子项1的flex-grow: 0(未设置默认为0), 子项2flex-grow: 2,子项3flex-grow: 1,剩余空间分成3份,子项2占2份(120px),子项3占1份(60px)。所以 子项1真实的占用空间为: 50+0 = 50px, 子项2真实的占用空间为: 70+120 = 190px, 子项3真实的占用空间为: 100+60 = 160px。
Flex 元素属性: flex-shrink
-
flex-grow
属性是处理flex元素在主轴上增加空间的问题,相反flex-shrink
属性是处理flex元素收缩的问题。如果我们的容器中没有足够排列flex元素的空间,那么可以把flex元素flex-shrink
属性设置为正整数来缩小它所占空间到flex-basis
以下。与flex-grow属性一
样,可以赋予不同的值来控制flex元素收缩的程度 —— 给flex-shrink
属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。 - 在计算flex元素收缩的大小时,它的最小尺寸也会被考虑进去,就是说实际上flex-shrink属性可能会和flex-grow属性表现的不一致。
举个例子
- 容器的宽度为400px, 子项1的占用的基准空间(flex-basis)为250px,子项2占用的基准空间是150px,子项3占用基准空间是100px,总基准空间为 250+150+100=500px。容器放不下,多出来的空间需要被每个子项根据自己设置的flex-shrink 进行吸收。 子项1的flex-shrink: 1(未设置默认为1), 子项2 flex-shrink: 2,子项3 flex-shrink: 2。子项1需要吸收的的空间为 (2501)/(2501+1502+1002) * 100 = 33.33px,子项1真实的空间为 250-33.33 = 216.67px。同理子项2吸收的空间为(1502)/(2501+1502+1002) * 100=40px,子项2真实空间为 150-40 = 110px。子项3吸收的空间为(1002)/(2501+1502+1002) * 100 = 26.67px,真实的空间为100-26.67=73.33px。
Flex元素属性的简写
- 你可能很少看到
flex-grow
,flex-shrink
,和flex-basis
属性单独使用,而是混合着写在flex
简写形式中。Flex
简写形式允许你把三个数值按这个顺序书写 —flex-grow
,flex-shrink
,flex-basis
。flex-grow
默认值是0,flex-shrink
默认值是,flex-basis
默认值是auto。 -
flex:1
相当于flex-grow:1,flex-shrink:1,flex-basis:0