;>
<div>11111</div>
<div>22222</div>
</div>
(1) 两者都为0
- width: 0 —— 完全没显示
- flex-basis: 0 —— 根据内容撑开宽度
(2) 两者非0
- width: 非0;
- flex-basis: 非0
—— 数值相同时两者等效
—— 同时设置,flex-basis优先级高
(3) flex-basis为auto
flex-basis为auto时,如设置了width则元素尺寸由width决定;没有设置则由内容决定
(4) flex-basis == 主轴上的尺寸 != width
- 将主轴方向改为:上→下
- 此时主轴上的尺寸是元素的height
- flex-basis == height
2. 常用的复合属性 flex
这个属性应该是最容易迷糊的一个,下面揭开它的真面目。
flex = flex-grow + flex-shrink + flex-basis
复合属性,前面说的三个属性的简写。
一些简写
flex: 1
= flex: 1 1 0%
flex: 2
= flex: 2 1 0%
flex: auto
= flex: 1 1 auto;
flex: none
= flex: 0 0 auto;
// 常用于固定尺寸 不伸缩
flex:1 和 flex:auto 的区别
其实可以归结于flex-basis:0
和flex-basis:auto
的区别。
flex-basis
是指定初始尺寸,当设置为0时(绝对弹性元素),此时相当于告诉flex-grow
和flex-shrink
在伸缩的时候不需要考虑我的尺寸;相反当设置为auto
时(相对弹性元素),此时则需要在伸缩时将元素尺寸纳入考虑。
因此从下图(转自W3C)可以看到绝对弹性元素如果flex-grow
值是一样的话,那么他们的尺寸一定是一样的。
五、容器内如何对齐
前面讲完了元素大小关系之后,下面是另外一个重要议题——如何对齐。可以发现上面的所有属性都是围绕主轴进行设置的,但在对齐方面则不得不加入作用于交叉轴上。需要注意的是这些对齐属性都是作用于容器上。
1. 主轴上的对齐方式
justify-content
2. 交叉轴上的对齐方式
主轴上比较好理解,重点是交叉轴上。因为交叉轴上存在单行和多行两种情况。
交叉轴上的单行对齐
align-items
默认值是stretch
,当元素没有设置具体尺寸时会将容器在交叉轴方向撑满。
当align-items
不为stretch
时,此时除了对齐方式会改变之外,元素在交叉轴方向上的尺寸将由内容或自身尺寸(宽高)决定。
注意,交叉轴不一定是从上往下,这点再次强调也不为过。
交叉轴上的多行对齐
还记得可以通过flex-wrap: wrap
使得元素在一行放不下时进行换行。在这种场景下就会在交叉轴上出现多行,多行情况下,flex布局提供了align-content
属性设置对齐。
align-content
与align-items
比较类似,同时也比较容易迷糊。下面会将两者对比着来看它们的异同。
首先明确一点:align-content
只对多行元素有效,会以多行作为整体进行对齐,容器必须开启换行。
align-content: stretch | flex-start | flex-end | center | space-between | space-around
align-items: stretch | flex-start | flex-end | center | baseline
在属性值上,align-content
比align-items
多了两个值:space-between
和space-around
。
align-content与align-items异同对比
与align-items
一样,align-content:
默认值也是stretch
。两者同时都为stretch
时,毫无悬念所有元素都是撑满交叉轴。
#container {
align-items: stretch;
align-content: stretch;
}
当我们将align-items改为flex-start
或者给弹性元素设置一个具体高度,此时效果是行与行之间形成了间距。
#container {
align-items: flex-start;
align-content: stretch;
}
/*或者*/
#container {
align-content: stretch;
}
#container > div {
height: 30px;
}
为什么?因为align-content
会以整行为单位,此时会将整行进行拉伸占满交叉轴;而align-items
设置了高度或者顶对齐,在不能用高度进行拉伸的情况下,选择了用间距。
尝试把align-content
设置为顶对齐,此时以行为单位,整体高度通过内容撑开。
而align-items
仅仅管一行,因此在只有第一个元素设置了高度的情况下,第一行的其他元素遵循align-items: stretch
也被拉伸到了50px。而第二行则保持高度不变。
#container {
align-items: stretch;
align-content: flex-start;
}
#container > div:first-child {
height: 50px;
}
两者的区别还是不明显?来看下面这个例子。
这里仅对第二个元素的高度进行设置,其他元素高度则仍保持内容撑开。
以第一个图为例,会发现align-content
会将所有行进行顶对齐,然后第一行由于第二个元素设置了较高的高度,因此体现出了底对齐。
两者差异总结:
- 两者“作用域”不同
- align-content管全局(所有行视为整体)
- align-items管单行
能否更灵活地设置交叉轴对齐
除了在容器上设置交叉轴对齐,还可以通过align-self
单独对某个元素设置交叉轴对齐方式。
- 值与
align-items
相同
- 可覆盖容器的
align-items
属性
- 默认值为
auto
,表示继承父元素的align-items
属性
#container {
display: flex;
align-items: flex-start;
}
#container > div:first-child {
align-self: stretch;
}
#container > div:nth-child(3) {
align-self: center;
}
#container > div:nth-child(4) {
align-self: flex-end;
}
六、其他
order:更优雅地调整元素顺序
#container > div:first-child {
order: 2;
}
#container > div:nth-child(2) {
order: 4;
}
#container > div:nth-child(3) {
order: 1;
}
#container > div:nth-child(4) {
order: 3;
}
order:可设置元素之间的排列顺序
- 数值越小,越靠前,默认为0
- 值相同时,以dom中元素排列为准