在学习 CSS Flex 的过程中遇到的一些疑问,将其记录下来。
将元素的 style 属性 display 设置成 flex ,那么改容器就变成了一个 flex 容器
.container {
display: flex;
}
复制代码
当一个元素被设置为 flex 容器后,flex 提供两类属性设置来控制容器子元素位置和宽高。分别是控制子元素位置分布,可控制子元素伸缩性
默认情况
子元素的 CSS
.box {
width: 100px;
height: 100px;
border: 2px solid black;
}
复制代码
默认情况下,子元素宽度总和比容器宽度小时,与一般的盒子模型表现没有什么不同。
如果子元素的宽度总和比容器宽度大时,每个子元素就会收缩,收缩的宽度为 (子元素宽度总和 – flex 容器宽度) * (子元素宽度 / 子元素宽度总和)。也就是说,子元素多出的宽度,由子元素占宽度总和的比例来分配。如下图,容器宽度为 600px,4 个小元素宽度为 100px,最有一个大元素的宽度为 400px,那么元素宽度总和就是 4 * 100 + 400 = 800px,比容器宽度多出 800 – 600 = 200px,多出的 200px 需要各个子元素压缩自己的宽度,以免子元素排布到容器外部。这 200px 就按比例分配个各个子元素。
可以看到,渲染出来的元素,小元素收缩了 25 px,大元素收缩了 100px。正好说明,子元素默认的收缩宽度是按照元素原来的 100:400 来分配的。
关于高度,上面的例子,子元素的高度被认为设置为 100px,如果子元素没有设置 height 属性,那么子元素的高度将被拉伸到和 flex 容器高度一样
由此可以得出,flex 容器的默认行为:默认子元素不换行,宽度够的情况子元素宽度就是自己的宽度,宽度不够的情况下,按各自宽度占总宽度的比例收缩,没有设置高度,子元素高度和 flex 容器一样高,从左往右排列
控制子元素分布
上面描述了默认情况下 flex 容器的子元素所表现出来的结果。下面来介绍通过属性控制子元素在 flex 容器中的子元素的位置,可以控制子元素分布的属性有下面几种
- justify-content:控制子元素在 flex 容器内的主轴上的分布,默认为 flex-start
- align-items:控制子元素在 flex 容器内交叉轴的分布,默认为 stretch,这也是为什么子元素不设置高度,默认为容器高度
- flex-direction:控制元素的排序方向,默认从左往右
- flex-wrap:当 flex 容器宽度不够时,是否需要换行,默认不换行
- align-content:当 flex 容器的子元素有多行时,控制行与行之间的分布情况
- align-self:单独控制某一个子元素在列上的分布表现
- order:控制子元素在容器中的排序
控制子元素伸缩
既然是 flex 布局,顾名思义,就有属性来控制元素的伸缩,CSS 提供 3 个属性来设置子元素在伸缩性上面的功能
- flex-grow:控制当一行的空间有剩余时,怎么分配剩余的控件,默认时不分配
- flex-shrink:控制当一行的空间为
- flex-basis:描述子元素的的宽度行为
默认子元素的 flex-grow 为 0,也就是说元素默认不伸长
- 当子元素所有的 flex-grow 和小于 1 时,子元素伸长的宽度为空余宽度的百分比,比如 flex-grow 为 0.5,那么子元素伸长 空余宽度 * 0.5
- 当子元素 flex-grow 大于 1 时,那么就按比例来伸长,比如一个元素 flex-grow 为 1,其他都是默认 0,那么这个元素将占居所有空余空间。或者,一个元素 flex-grow 为 1,另一个为 0.5,其他都为 0,那么剩余的空间将按照 2 : 1 的比例分配给两个 flex-grow 不为 0 的元素上。
flex-shrink 默认为 1,也就是说默认情况下,每一个子元素的按比例收缩
flex-basis 默认为 auto,也就是按照子元素自己的宽度表现,如果有设置 flex-basis,那么 width 将不起作用。
简写属性
除了上面介绍的属性,CSS 还提供了一些 flex 的简写属性
- flex-flow 为 flex-direction,flex-wrap 的简写
- flex 为 flex-grow,flex-shrink,flex-basis 的简写