flex
基本概念
flexbox是一种一维的布局模型,它给flexbox的子元素之间提供了强大的空间分布和对齐能力。我们说它是一种一维的布局,是因为一个flexbox一次只能处理一个维度上的元素布局,一行或者一列,作为对比的是另外一个二维布局grid,可以同时处理行和列上的布局
两根轴线
主轴
由flex-direction定义,可以取四个值
- row
- row-reverse
- column
- column-reverse


交叉轴
交叉轴是垂直于主轴的,主轴是什么方向,交叉轴就是垂直于主轴的另一个方向。flexbox的特性是沿着主轴或者交叉轴对齐之中的元素
Flex容器
文档中采用了flexbox的区域就叫做flex容器,为了创建flex容器,将一个容器的display属性值改为flex或者inline-flex。之后容器中的直系子元素就会变为flex元素
- 元素排列为一行 (flex-direction 属性的初始值是 row)。
- 元素从主轴的起始线开始。
- 元素不会在主维度方向拉伸,但是可以缩小。
- 元素被拉伸来填充交叉轴大小。
- flex-basis 属性为 auto。
- flex-wrap属性为 nowrap。
这会让元素呈线性排列,并且把自己的大小作为主轴上的大小。如果有太多元素超出容器,它们会溢出而不会换行,如果一些元素比其他元素高,那么元素会沿交叉轴被拉伸来填满它的大小。
多行flex容器
使用flex-wrap可以将一维的flexbox应用到多行中。在这样做的时候,应该把每一行看做一个新的flex容器,任何空间分布都将在该行上发生,而不影响该空间其他行的分布。给flex-wrap赋值为wrap后,若项目的子元素总宽度大于容器最大宽度,子元素将会换行显示。若设置为nowrap,子元素将会缩小以适应容器,若不能缩小,则会溢出。
简写flex-flow
可以将flex-direction和flex-wrap简写为flex-flow。
flex子元素属性
首先介绍可用空间 available space 这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的可用空间的行为。同时,可用空间对于 flex 元素的对齐行为也是很重要的。
假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的可用空间。在默认情况下,flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。

如果期望这些元素能自动地扩展去填充满剩下的空间,那么我们需要去控制可用空间在这几个元素间如何分配,这就是元素上的那些 flex 属性要做的事。
flex-basis
定义了该元素的空间大小,如果给元素设定了尺寸,那么它的值就是设定的尺寸;如果没有给元素设定尺寸,以包含的内容决定宽度;如果给basis设定了content,则一律以内容决定宽度;若设定了长度或百分比值,则根据这个值设定宽度;
根据以上规则知道了每一项的宽度,简单相加就能得到所有项的宽度总和。而知道了总和,再与容器宽度比较,就能知道容器里是不是还有剩余空间可供再次分配。这里有三种情况:
- 所有项宽度总和等于容器宽度,剩余空间为零
- 所有项宽度总和小于容器宽度,剩余空间为正
- 所有项宽度总和大于宽度宽度,剩余空间为负
剩余空间为正,代表有剩余空间可分配,也就是可伸缩项有条件扩展。至于如何扩展,那就要看每一项的flex-grow属性了。
剩余空间为负,代表可伸缩项宽度总和超出了容器宽度,也就是可伸缩项必须收缩才能适应容器宽度。至于如何收缩,就得看每一项的flex-shrink属性。
与width的区别
-
为0时
width为0,完全不显示;basis为0,根据内容撑开宽度
-
非0时
数值相同时两者等效;同时设置,basis优先级高
-
basis为auto
如设置了width由则元素尺寸由width决定,没有设置则由内容决定
-
basis是主轴的尺寸,不一定是width
flex-basis:0与flex-basis:auto的区别
设置为0时(绝对弹性元素),此时相当于告诉flex-grow和flex-shrink在伸缩的时候不需要考虑我的尺寸;相反当设置为auto时(相对弹性元素),此时则需要在伸缩时将元素尺寸纳入考虑。下图可以看出如果grow值一样,元素尺寸一定是一样的
flex-grow
本属性用于设定在容器宽度大于元素总宽度时如何伸展
必须是正整数?,默认值为0,代表不扩展,只要有一项子元素的flex-grow不为0,就要对容器剩余宽度进行分配。分配规则如下
当前项可分得的剩余空间=(当前项grow值/所有项grow值之和)*剩余总宽度
flex-shrink
本属性用于设定在容器宽度小于元素总宽度时如何收缩
必须是正整数?,默认值为1,默认每一项都会收缩,shrink与grow不同,会进行按权收缩,规则如下
当前项收缩的宽度 = ( 当前项flex-shrink*当前项flex-basis / 所有项flex-shrink与各自flex-basis乘积之和 ) * 需收缩的总宽度
除了考虑shrink本身,也要考虑basis,如果每一项shrink都是1,那其实就是按照每一项basis的占比按权收缩,防止宽度小的元素被收缩为0宽度
flex
flex: 1=flex: 1 1 0%flex: 2=flex: 2 1 0%flex: auto=flex: 1 1 auto;flex: none=flex: 0 0 auto;// 常用于固定尺寸 不伸缩
order
本属性用于调整子元素顺序,数值越小,越靠前,默认为0;值相同时,以dom元素的排列为准
轴线对齐方式
justify-content
align-item
单行对齐
多行对齐align-content
只在有多行元素时生效
默认值stretch,item与content同时为stretch时,效果为撑满交叉轴
content为stretch,item为flex-start或给弹性元素设置一个具体高度时,行与行之间会形成间距
content会以整行为单位拉伸撑满交叉轴,而item设置了高度或者顶对齐,不能使用高度进行拉伸,使用间距进行拉伸
item设为stretch,content设为flex-start,此时以行为单位,整体高度通过内容撑开,
align-self可以单独对某个元素设置交叉轴对齐方式
grid
基本概念
网格是一组相交的水平线和垂直线,它定义了网格的列和行,我们可以将网格元素放置在与这些行和列相关的位置上。
CSS 网格布局具有以下特点:
固定的位置和弹性的轨道的大小
你可以使用固定的轨道尺寸创建网格,比如使用像素单位。你也可以使用比如百分比或者专门为此目的创建的新单位 fr来创建有弹性尺寸的网格。
元素位置
你可以使用行号、行名或者标定一个网格区域来精确定位元素。网格同时还使用一种算法来控制未给出明确网格位置的元素。
创建额外的轨道来包含元素
可以使用网格布局定义一个显式网格,但是根据规范它会处理你加在网格外面的内容,当必要时它会自动增加行和列,它会尽可能多的容纳所有的列。
对齐控制
网格包含对齐特点,以便我们可以控制一旦放置到网格区域中的物体对齐,以及整个网格如何对齐。
控制重叠内容
多个元素可以放置在网格单元格中,或者区域可以部分地彼此重叠。然后可以 CSS 中的z-index属性来控制重叠区域显示的优先级。
网格容器
在元素上声明display:grid来创建一个网格容器,这个元素的所有直系子元素将成为网格元素,网格默认给这些元素创建单列网格;
网格轨道
通过grid-template-column和grid-template-rows属性来定义网格中的行和列,这些属性定义了网格的轨道。一个网格轨道就是网格中任意两条线之间的空间。
-
grid-template-columns: 200px 200px 200px;===grid-template-columns: repeat(3, 200px);固定的列宽与列数量;repeat可以简化重复的值
-
grid-template-columns: repeat(auto-fill, 200px);自动填充,设定了列宽,但是不限定列数量,只要放得下就可以放置元素
-
grid-template-columns: 1fr 2fr 1fr;自动将容器分成相等宽度的n份进行分配
-
grid-template-columns: 1fr 1fr minmax(300px, 2fr);赋给一个网格元素最大最小的尺寸,第三个列宽最少也是要 300px,但是最大不能大于第一第二列宽的两倍。
-
grid-template-columns: 100px auto 100px;第一第三列为 100px,中间由浏览器决定长度;auto最小为内容的宽度
rows属性与column相同,仅变为操作行
fr单位
轨道可以使用任何长度单位进行定义,新的fr单位代表网格容器中可用空间的一等份
隐式和显示网格
grid-template-columns 属性定义了自己的列轨道,让网格按所需的内容创建行,这些行会创建在隐式网格中。
可以在隐式网格中用 grid-auto-rows 和 grid-auto-columns 属性来定义一个设置大小尺寸的轨道。网格自行创建的行或列会按照这个尺寸进行创建。
跨轨道放置网格元素
- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
网格间距
grid-row-gap 属性、grid-column-gap 属性分别设置行间距和列间距。grid-gap 属性是两者的简写形式。grid-row-gap: 10px 表示行间距是 10px,grid-column-gap: 20px 表示列间距是 20px。grid-gap: 10px 20px 实现的效果是一样的
其他高级属性
grid-template-areas
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-areas:
". header header"
"sidebar content content";
background-color: #fff;
color: #444;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
以上代码表示将类 .sidebar .content .header所在的元素放在上面 grid-template-areas 中定义的 sidebar content header 区域中
grid-auto-flow
grid-auto-flow 属性控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图英文数字的顺序 one,two,three...。这个顺序由 grid-auto-flow 属性决定,默认值是 row。
grid-auto-flow: row dense,表示尽可能填满表格,效果如下图
设置 grid-auto-flow: column,表示先列后行
当抉择该用网格还是弹性盒时,你可以问自己一个简单的问题
- 我只需要按行或者列控制布局?那就用弹性盒子
- 我需要同时按行和列控制布局?那就用网格