什么是Flex布局?
- flex布局是flexible Box的缩写,意为“弹性盒子”
- 使用flex布局的元素称为容器(flex container),该容器里面所有的子元素称为项目(flex item)。
- 它是用来为盒状模型提供最大的灵活性,可以随着页面大小的改变自适应页面布局
flex布局元素
- Flex 父元素(flex container),简称"父元素"。它的所有子元素自动成为父元素成员,称为 Flex 子元素(flex item),简称"子元素"。
- 任何一个父元素都可以指定为 Flex 布局
父项属性(flex container)
flex-direction-方向
- flex-direction用于指定主轴的方向, 有四个值, 默认是row,水平方向。项目始终沿着主轴的方向排列,如果改变了flex-direction,项目的布局排列就会跟着发生变化。
flex-direction: row|row-reverse|column|column-reverse;- 决定主轴的方向(即子元素的排列方向)
-
flex-direction:row(默认值):主轴为水平方向,从左往右 -
flex-direction:row-reverse:主轴为水平方向,从右到左(和row是相反的) -
flex-direction: column:主轴为垂直方向,从上至下 -
flex-direction: column-reverse:主轴为垂直方向,从下往上
-
flex-warp-换行
- flex-wrap 用于确定项目元素是否换行展示, 当所有 item 在主轴(假设主轴为水平方向 flex-direction:row)的宽度之和超过容器的大小,可以用flex-wrap决定是否换行显示。
flex-wrap: no-wrap|wrap|wrap-reverse;- 默认值为no-wrap,表示不换行,当项目的宽度超出时,会自动缩小item的宽度,确保他们都显示在一行。
- flex-warp-换行属性:
-
flex-wrap: no-wrap:(默认):不换行- 设置父盒子400px;子盒子100px;
-
flex-wrap: wrap:换行,第一行在上方 -
flex-wrap: wrap-reverse;换行,第一行在下方
-
flex-flow-流向
- flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
- 方向+换行一起决定了流向
flex-flow: <flex-direction> + <flex-wrap>;
justify-content-主轴对齐方式
- justify-content 用于指定item在主轴对齐方式, item可沿着主轴开始方向(flex-start)对齐、结束方向(flex-end)对齐、居中对齐(center)、两端对齐(space-between)、两侧对齐(space-around)。
- justify-content属性:
-
justify-content: flex-start;(默认值):沿主轴开始方向对齐 -
justify-content: flex-end;:沿主轴结束方向对齐 -
justify-content: center;:居中对齐 -
justify-content: space-between;:两端对齐,子元素之间的间隔都相等。 -
justify-content: space-around;:每个子元素两侧的间隔相等。所以,子元素之间的间隔比子元素与边框的间隔大一倍。
-
align-items-交叉轴对齐方式
- align-item 定义了项目在交叉轴方向的对齐方式,同样有沿轴的开始方向(flex-start)对齐,结束方向对齐(flex-end)对齐和居中对齐(center)baseline和stretch。
align-items: flex-start | flex-end | center | baseline | stretch(default)- align-item属性:
-
align-items: flex-start;:交叉轴的起点对齐。 -
align-items:flex-end;:交叉轴的终点对齐。 -
align-items:center;:- 交叉轴的中点对齐。 -
align-items: baseline;:子元素的第一行文字的基线对齐。 -
align-items:stretch(default);:如果子元素未设置高度或设为auto,将占满整个父元素的高度。
-
align-content-多行交叉轴对齐方式
- align-content属性定义了多根轴线的对齐方式。如果子元素只有一根轴线,该属性不起作用。
- align-content: flex-start | flex-end | center | space-between | space-around | stretch(default);
- align-content属性:
flex-start:与交叉轴的起点对齐。flex-end:与交叉轴的终点对齐。center:与交叉轴的中点对齐。space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch(默认值):轴线占满整个交叉轴。
align-content vs align-items
- 相同点:都被用来设置对齐行为
- 不同点:
- align-items 的设置对象是行内成员;
- align-content 的设置对象是所有行,且只有在多行弹性盒子容器中才生效。
子元素的属性
order 顺序
- order: integer;
- 属性定义子元素的排列顺序。数值越小,排列越靠前,默认为0。
flex-grow-放大
- 父元素空间充足,子元素默认不变
- flex-grow属性定义子元素的放大比例,默认为
0,即如果存在剩余空间,也不放大。 - 子元素flex-grow的值越大所占比例越大
- 使用场景:子元素默认是不会放大的,所以使用的场景是父元素空间充足时,子元素需要放大/子元素放大比例不一
- 如果所有子元素的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个子元素的flex-grow属性为2,其他子元素都为1,则前者占据的剩余空间将比其他项多一倍。
- 如果容器压根就没有剩余空间,那么即使你设置了flex-grow不会生效
- 案例解析:
-
flex-grow 的默认值为0,子项目不进行任何比例的拉伸,如果将3个子项目的flex-grow属性都设置为1, 那么他们将按照1:1:1的比例来分配剩余的100px空间。每个子项目的宽度就有133.3px了。
-
如果只给A项目设置flex-grow的属性为1,其它两个默认为0, 他们的比例就是1:0:0,意味着所有的剩余空间都给了A,A就有200px了。
.a { width: 100px; background-color: #61dafb; flex-grow: 1; } -
如果A、B、C三个项目的flex-grow 分别设置为 1:2:3, 那么他们将按照比例来瓜分剩余空间啊,就像下面这样
-
flex-shrink-缩小
- 父元素空间不足,子元素默认等比缩小
- flex-shrink属性定义了子元素的缩小比例,默认为1,即如果空间不足,该子元素将缩小。
- 和flex-grow刚好相反,子元素flex-shrink的值越大所占比例越小
- 默认是会等比缩小的,所以使用的场景是空间不足时,子元素缩小比例不同/不需要缩小
- 如果所有子元素的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个子元素的flex-shrink属性为0,其他子元素都为1,则空间不足时,前者不缩小。负值对该属性无效。
flex-shrink: <number>; /* default 1 */- 案例:
-
我将容器的宽度设置为200px, 3个子项目的宽度都是100px, 这时容器的宽度不足,默认情况下3个项目的宽度都进行等比例压缩,变成了66.67px。
-
如果不希望被压缩,我们可以选择换行,只要设置 flex-wrap 属性为 wrap 就好。
-
为什么C的长度是A和B的长度之和呢?因为 C 换行后独占一行,相当于在第二根主轴方向只有它,这时候你又设置了flex-grow的值,所以它会把所有剩余空间全部占满。
-
如果选择不换行对项目进行压缩的话,就可以使用flex-shrink 属性,数值越大,压缩越多。具体压缩多少呢?这个要看溢出的空间有多少。flex-shrink 为0时不压缩。
-
如果容器还有剩余空间,设置flex-shrink也是无效的。
-
flex-basis-
-
flex-basis 表示项目在主轴的空间(flex-direction为row时就是项目的宽度),默认值是auto,即项目本来的宽度。计算主轴还有多少剩余空间就是用来这个属性来计算。
-
项目的实际宽度有个优先级:max-width/min-width > flex-basis > width > box, 意味着这些属性同时存在时,优先取 max-width和min-width。
-
flex-grow, flex-shrink 和 flex-basis 可以用一个flex属性将三个值组合在一起。
-
flex-basis属性:
.item { flex:0; } 等价于 .item { flex-grow: 0; flex-shrink: 1; flex-basis: 0%; } .item { flex:1; } 等价于 .item { flex-grow: 1; flex-shrink: 1; flex-basis: 0%; }
flex
-
取值:默认0 1 auto,flex属性是flex-grow,flex-shrink与flex-basis三个属性的简写,用于定义项目放大,缩小与宽度。
-
flex属性:
- flex:auto; 相当于(1 1 auto) 等分放大缩小
- flex:none; 相当于(0 0 auto) 不放大不缩小
- flex:1; 相当于(1 1 0px)
-
例子1: 两端固定,中间自适应布局
-
等分份数
flex:auto和flex:1的区别
- 实际上就是flex-basis为0%和auto的区别,auto为默认值即为子元素的大小
- flex-basis为0%,可以覆盖width
- flex-basis为auto,width权限更高
- flex:auto=>flex-basis:auto 表示flex-basis:$width 是相当于设置了Flex-basis为宽度
- flex:1=>flex-basis:0 相当于未设置flex-basis
- 存在多余空间时,flex为1,width将会被忽略;flex为auto时,width的设置将是有效的
align-self
- align-self属性允许单个子元素有与其他子元素不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
- 单个子元素有与其他子元素有不一样的对齐方式
- align-self: auto | flex-start | flex-end | center | baseline | stretch;
- 该属性可能取6个值,除了auto,其他都与align-items属性完全一致