简短回答
虽然flex-wrap
属性看起来非常基本-它控制Flex项是否可以换行-但它实际上对整个FlexBox布局有广泛的影响.
flex-wrap
属性确定您将使用的弹性容器的类型.
flex-wrap: nowrap
等于101
flex-wrap: wrap
和wrap-reverse
创建102
align-items
个个和align-self
个属性可在单行和多行容器中使用.但是,只有在挠性线的横轴上有空闲空间时,它们才能起作用.
对齐-内容
个个属性仅适用于多行容器.它在单行容器中被忽略.
解释
flexbox specification提供了四个用于对齐FLEX项目的关键字属性:
align-items
个个
align-self
个
对齐-内容
个个
justify-content
个
要理解这些属性的功能,首先要了解Flex容器的 struct ,这一点很重要.
第1部分:了解Flex容器的主轴和横轴
100
flex容器在两个方向工作:x轴(水平)和y轴(垂直).
来源:Wikipedia
Flex容器的子元素-称为"Flex Items"-可以在任一方向上对齐.(忽略上图中的z轴.它不适用于这里.)
这是最基本级别的灵活对齐.
100
在柔性布局中,覆盖x和y轴的是main和cross轴.
默认情况下,主轴为水平轴(x轴),横轴为垂直轴(y轴).这是初始设置,由flexbox specification定义.
*>来源:W3C<来源:W3C<
但是,与固定的x轴和y轴不同,主轴和十字轴可以切换方向.
101
在上图中,主轴是水平的,横轴是垂直的.如前所述,这是Flex容器的初始设置.
但是,使用flex-direction
属性可以很容易地切换这些方向.此属性控制主轴的方向;它确定弹性项是垂直对齐还是水平对齐.
From the spec:个
5.1. Flex Flow Direction: the flex-direction
property个
flex-direction
属性指定如何将flex项放置在
flex-direction
属性有四个值:
/* main axis is horizontal, cross axis is vertical */
flex-direction: row; /* default */
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
十字轴始终垂直于主轴.
第2部分:折线
在容器内,弹性项存在于一条线中,称为"弹性线".
折线是一行或一列,取决于flex-direction
.
一个容器可以有一行或多行,具体取决于flex-wrap
行.
100
flex-wrap: nowrap
建立单行弹性容器,在该容器中,弹性项被强制留在单行中(即使它们溢出容器).
The image above has one flex line.
flex-container {
display: flex;
flex-direction: column;
flex-wrap: nowrap; /* <-- allows single-line flex container */
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
width: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
100
flex-wrap: wrap
或wrap-reverse
建立多行弹性项容器,弹性项可以在其中创建新行.
The image above has three flex lines.个个
flex-container {
display: flex;
flex-direction: column;
flex-wrap: wrap; /* <-- allows multi-line flex container */
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
width: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
The image above has three flex lines.个个
flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap; /* <-- allows multi-line flex container */
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
第3部分:关键字对齐属性
100
flex-direction
属性控制弹性项的布局方向,而有四个属性控制对齐和定位.这些是:
align-items
个个
align-self
个
对齐-内容
个个
justify-content
个
这些属性中的每一个都被永久指定给一个轴.
justify-content
个号房产仅在主轴上使用.
三个align-*
属性仅在横轴上工作.
假设这些属性固定在x轴和y轴上是一个常见的错误.例如,justify-content
个总是水平的,而align-items
个个总是垂直的.
但是,当flex-direction
切换到column
时,主轴变为y轴,justify-content
个垂直工作.
这篇文章的重点是横轴对齐.有关主轴对齐和justify-content
个属性的说明,请参阅以下帖子:
100
FlexBox规范提供了三个用于交叉轴对齐的关键字属性:
align-items
个个
align-self
个
对齐-内容
个个
align-items
个个 / align-self
个
align-items
个个属性沿弹性线的横轴对齐弹性项目.它适用于柔性容器.
align-self
个属性用于覆盖单个弹性项上的align-items
个个.它适用于弹性项目.
以下是规范中的定义:
8.3. Cross-axis Alignment: the align-items
个个 and align-self
个
properties个
弹性项目可以在当前行的横轴上对齐
align-items
个个/align-self
个有六个可能的值:
flex-start
个
flex-end
个个
center
个
baseline
个
stretch
个
auto
(align-self
个 only)
(有关每个值的说明,请单击上面的等级库定义标题.)
初始值align-items
个个是stretch
个,这意味着柔体项目将扩展容器横轴的全部可用长度.
初始值align-self
个是auto
,表示它继承值align-items
个个.
下面是行方向容器中每个值的效果图示.
*>来源:W3C<
对齐-内容
个个
此属性比align-items
个个和align-self
个稍微复杂一些.
以下是规范中的定义:
8.4. Packing Flex Lines: the 对齐-内容
个个
property
对齐-内容
个个属性将flex容器中的行对齐
与移动弹性项within their line的align-items
个个和align-self
个相比,对齐-内容
个个移动弹性线within the container.
对齐-内容
个个有六个可能的值:
flex-start
个
flex-end
个个
center
个
space-between
个
space-around
个
stretch
个
(有关每个值的说明,请单击上面的等级库定义标题.)
下面是行方向容器中每个值的效果图示.
*>来源:W3C<
101
在单线柔性容器中,线的交叉尺寸等于容器的交叉尺寸.这意味着线和容器之间没有自由空间.因此,对齐-内容
个个可能没有效果.
以下是前relevant section from the spec名:
因为在单线柔性容器中,唯一的线会自动伸展以填充空间,所以只有多线柔性容器在横轴上有空闲空间可供线条对齐.
第4部分:示例说明
在示例1中,align-self
个适用于flex-wrap: nowrap
,因为弹性项存在于单行容器中.因此,有一条弹性线,它与容器的高度相匹配.
flex-container {
display: flex;
flex-wrap: nowrap;
对齐-内容: flex-start;
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
flex-item:last-child {
align-self: flex-end;
background-color: crimson;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
在示例#2中,align-self
个失败,因为它存在于多行容器(flex-wrap: wrap
)and中,对齐-内容
个个被设置为flex-start
个.这意味着挠性线紧紧地堆积在十字轴的起始处,没有给align-self
个留出空闲的工作空间.
flex-container {
display: flex;
flex-wrap: wrap;
对齐-内容: flex-start;
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
flex-item:last-child {
align-self: flex-end;
background-color: crimson;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
示例#3的解释与示例#1相同.
flex-container {
display: flex;
flex-wrap: nowrap;
align-items: flex-end;
对齐-内容: flex-start;
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
示例#4的解释与示例#2相同.
flex-container {
display: flex;
flex-wrap: wrap;
align-items: flex-end;
对齐-内容: flex-start;
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
示例5是单行容器.因此,挠性线的十字大小等于容器的十字大小,在两者之间没有留下额外的空间.因此,对齐挠性线when there is extra space in the cross axis的对齐-内容
个个没有任何效果.
flex-container {
display: flex;
flex-wrap: nowrap;
对齐-内容: center;
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
对齐-内容
个个的初始设置为stretch
个.这意味着,如果未指定其他值,容器将在柔性线之间均匀分配可用空间.(当所有弹性项目都达到flex: 1
时,主轴上会产生类似的效果.)
行之间的这种空间分布可能会导致行/列之间出现较大的间隙.线越少,间隙越大.线越多,间隙越小,因为每一条线所占的空间越小.
要解决此问题,请从对齐-内容: stretch
切换到对齐-内容: flex-start
.这会将这些行打包在一起(请参见上面的示例#2和#4).当然,这也消除了队列中的任何空闲空间,align-items
个个和align-self
个不能再工作.
这里有一个相关帖子:Remove space (gaps) between multiple lines of flex items when they wrap
flex-container {
display: flex;
flex-wrap: wrap;
/* 对齐-内容: center; */
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>
正如在前面的示例中所解释的,对于对齐-内容: stretch
,弹性线中可以有额外的空间,这允许align-items
个个和align-self
个工作.对齐-内容
个个的任何其他值都会填充这些行,从而消除额外的空间,并使align-items
个个和align-self
个变得毫无用处.
flex-container {
display: flex;
flex-wrap: wrap;
/* 对齐-内容: center; */
width: 250px;
height: 250px;
background-color: silver;
}
flex-item {
flex: 0 0 50px;
height: 50px;
margin: 5px;
background-color: lightgreen;
}
flex-item:nth-child(even) {
align-self: flex-end;
background-color: crimson;
}
<flex-container>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-container>