参考:
《CSS权威指南》(第四版)
前言
布局一直是CSS中最重要的功能。CSS2的时代,float和inline-block布局是主流的布局方式,然而这些布局方式脱离了这些css属性原本设计的初衷,造成理解成本高,同时有诸多局限。flex布局与弹性布局是专为现代web开发设计的布局方式,可以解决很多之前布局方式难以解决的问题。
Flex布局是什么
FlexBox,弹性盒布局,顾名思义,就是元素具有弹性,能根据可用空间大小增减尺寸。
基本概念
- 弹性盒:在任何元素上声明
display:flex
或display: inline-flex
便激活弹性盒布局,这个元素就成为了弹性容器
(flex container)。 - 弹性元素:弹性容器的子元素成为
弹性元素
(flex item)。 - 主轴和交叉轴:flexbox的
❗注意:**弹性容器内的子元素,都会变为块级元素,**而不管原先是内联还是块级,包括匿名内联元素。
弹性容器上属性
弹性容器为其子元素生成弹性格式化上下文,这些子元素不论是DOM节点、文本节点,还是生成的内容,都称为弹性元素。
弹性容器中的绝对定位元素
(position:absolute)
也是弹性元素。
flex-direction
flex-direction
属性决定主轴的方向(即项目的排列方向)。
.box { flex-direction: row | row-reverse | column | column-reverse; }
flex-wrap
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap
属性定义,如果一条轴线排不下,如何换行。
它可能取三个值。
(1)nowrap
(默认):不换行。
(2)wrap
:换行,第一行在上方。
(3)wrap-reverse
:换行,第一行在下方。
flex-flow
flex-flow
属性是flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
。
justify-content
justify-content
定义在弹性元素在主轴上的对齐方式。
有5个取值:
INFO
<font style="color:rgb(17, 17, 17);">flex-start</font>
<font style="color:rgb(17, 17, 17);">flex-end</font>
<font style="color:rgb(17, 17, 17);">center</font>
<font style="color:rgb(17, 17, 17);">space-between</font>
<font style="color:rgb(17, 17, 17);">space-around</font>
align-items
定义弹性元素在交叉轴如何对齐
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
INFO
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content
align-content
指定在垂轴方向上如何对齐多行弹性元素。所以align-content
属性值只适用于多行显示的弹性容器,对禁止换行和只有一行的弹性容器没有影响。
align-content
属性与align-items
在取值和相关概念上是一样的,但二者的作用不同,align-items
指定的是每一行中弹性元素的定位方式。而align-content
属性更类似于justify-content
,只不过它的作用是指定如何在垂轴方向上对齐多行弹性元素。
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
该属性可能取6个值。
INFO
flex-start
:与交叉轴的起点对齐。flex-end
:与交叉轴的终点对齐。center
:与交叉轴的中点对齐。space-between
:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch
(默认值):轴线占满整个交叉轴。
容器内子项目属性
order
order
属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item { order: <integer>; }
align-self
属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
flex 属性(flex的精髓)
控制弹性元素在主轴上的比例 - CSS:层叠样式表 | MDN
INFO
弹性布局最突出的一点是能把弹性元素变得具有"弹性"。
****
比如说下边这个例子:有一个500px宽的容器,但3个弹性元素都为200px宽,那我们一共需要600px宽,因此就有了100px的负可用空间。
****flex-basis
**<font style="color:rgb(27, 27, 27);">flex-basis</font>**<font style="color:rgb(27, 27, 27);"></font>
``****
<font style="color:rgb(27, 27, 27);">auto</font>
<font style="color:rgb(27, 27, 27);">width</font>
flex-grow
flex-grow属性的值为一个数字,默认为0。
flex-grow
用于设置弹性元素在弹性容器中分配正向可用空间的相对比例。
看下边这个例子就可以直观理解flex-grow作用机制:弹性容器宽度为750px,容器内有三个设置了width为100px的弹性元素,此时容器内的正向可用空间为450px。下图中的第一个例子,三个弹性元素的flex-grow都为0,此时弹性元素都不会增大;第二个例子:第三个弹性元素flex-grow为1,此时所有正向空间会分为1份,都会分配给第三个元素。第三个例子:正向空间会分为5份,每份90px,所以第一、二个元素宽度为190px(100+90),第三个元素为370px(100+90×3);
flex-shrink
flex-shrink
用于设置弹性元素在弹性容器中分配负向可用空间的相对比例。
flex 弹性元素的大小
flex 属性
flex属性是flex-grow、flex-shrink、flex-basis的简写。
INFO
💡标准制定人员更推荐始终使用flex简写属性,而不是使用flex-grow等属性。
常见的flex值有四个,涵盖了最常需要的效果:
- flex:initial,这个值根据width或height属性确定弹性元素的尺寸。相当于flex: 0 1 auto;
- flex: auto,相当于"flex: 1 1 auto。效果与flex:initial类似,不过弹性元素变形是双向的;如果容器空间放不下全部弹性元素,元素将缩小;如果有额外空间,弹性元素将增大;
- **flex: none,**禁止弹性元素变形,相当与flex:0 0 auto;
- flex: number,取单个数值,比如flex: 1相当于 flex: 1 0 0 。此时弹性元素具有弹性,可以增大。常与min-width等限制最小尺寸的属性一起使用。
flex完整语法如下:
- 单值语法
- [flex-grow](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow)
- [flex-basis](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis)
- [flex-grow](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow)
- [flex-shrink](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-shrink)
- [flex-basis](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis)
- [flex-grow](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow)
- [flex-shrink](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-shrink)
- [flex-basis](https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis)
/* 单值,无单位数字:flex-grow flex-basis 此时等于 0。 */
flex: 2;
/* 单值,宽度/高度:flex-basis */
flex: 10em;
flex: 30px;
flex: min-content;
/* 双值:flex-grow | flex-basis */
flex: 1 30px;
/* 双值:flex-grow | flex-shrink */
flex: 2 2;
/* 三值:flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;
与absolute等定位的关系
分为两种情况:
- 在flex弹性元素子项上设置absolute,此时弹性元素子项会脱离文档流,不参与flex容器内的弹性元素尺寸计算。
- 在flex容器上设置absolute,此时弹性元素子项如果设置了
弹性布局的实际案例
两栏/三栏的响应式布局
比如实现这种一栏固定,两栏固定,中间内容框随视口变化。
.aside{
flex-grow:0 ;
}
.content{
flex:1
}
流式布局
.box {
display: flex;
flex-wrap: wrap;
}
.box div {
width: 100px;
height: 100px;
border: 1px solid;
}
居中对齐
flex布局可以轻易实现居中对齐
总结
- 弹性布局具有很多优势,比如弹性布局内的弹性元素margin不合并,可以轻易实现垂直居中、水平居中等。
- 弹性布局包括主轴和交叉轴
- flex布局有很多属性值,可以分为两类:设置在弹性容器内的属性值和弹性元素上的属性值。
- flex属性是flex布局具有"弹性"的关键。弹性元素的尺寸计算有一套规则,受到flex-basis、flex-grow、flex-shrink等属性共同作用。
- flex布局可以轻易实现水平垂直居中、两栏/三栏响应式布局、流式布局。