flex 布局#
块级元素和行内元素#
块级元素:独占一行(前后会自动换行),自动填满父容器的宽度。它们的 display 属性为 block。
行内元素:与其他行内元素排在一行内,宽高由内容决定。它们的 display 属性为 inline。
大部分 html 元素都是块级元素或行内元素。
下面是一个例子,一个 container 中装了 3 个 item。
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>html这里的 item 都是块级元素,它们都独占一行,自上而下排列。
为了方便展示,示例中的 container 容器使用 红色边框,其中的 item 项目使用 蓝色方块。
flex 容器和 flex 元素#
在容器元素的 CSS 中添加 display: flex,它就会变为 flex 容器。
flex 容器的直接子项目都是 flex 元素。
.container {
display: flex;
}css可以看到,flex 容器中的 item 项目会自动排列在一行内。
flex 容器的主轴#
flex 布局的主轴默认为水平方向,主轴方向由 flex-direction 属性控制,默认为 row。
.container {
display: flex;
flex-direction: row;
}css如果将主轴方向 flex-direction 设为 row-reverse(翻转),那么元素则会反方向排列。
.container {
display: flex;
flex-direction: row-reverse;
}css沿轴线方向对齐#
沿主轴对齐#
flex 容器内的元素会沿着主轴方向排列,在 flex 容器上使用 justify-content 属性可以控制容器内元素在主轴上的位置。justify-content 有以下几个常用的取值。
start:对齐主轴起点,这是默认行为。
.container {
display: flex;
justify-content: start;
}cssend:对齐主轴终点。
.container {
display: flex;
justify-content: end;
}csscenter:在主轴上居中。
.container {
display: flex;
justify-content: center;
}cssspace-between:均匀分配每个 item 的间隙(item 之间)。
.container {
display: flex;
justify-content: space-between;
}css两侧不留间隙,只在 item 之间均匀分配。
space-around:均匀分配每个 item 两侧的空间(周围)。
.container {
display: flex;
justify-content: space-around;
}cssitem 之间的间隙是侧边的两倍。
space-evenly:均匀分配每个 item 的间隙(包括侧边的)。
.container {
display: flex;
justify-content: space-evenly;
}css两侧留出间隙,所有间隙都均匀分配。
gap:手动设置间隙
手动指定 flex 元素之间的间隙。
.container {
display: flex;
gap: 20px;
}css沿交叉轴对齐#
交叉轴垂直于主轴,使用 align-items 属性可以调整元素在交叉轴上的对齐方式。
为了方便展示纵向对齐,这里增加了 容器边框 的高度。
- 对齐交叉轴起点
align-items 的默认值也是 start。
.container {
display: flex;
align-items: start;
}css- 对齐交叉轴终点
.container {
display: flex;
align-items: end;
}css- 居中对齐
.container {
display: flex;
align-items: center;
}css同时使用 justify-content: center 和 align-items: center,可以轻松让元素水平垂直居中。
.container {
display: flex;
justify-content: center;
align-items: center;
}css旋转主轴方向#
设置 flex-direction 为 column,可以将主轴方向设为纵向,交叉轴方向同时变为横向。
.container {
display: flex;
flex-direction: column;
}css由于现在的交叉轴是横向的,所以此时要让元素水平居中,应该调整 align-content 而不是 justify-content。
.container {
display: flex;
flex-direction: column;
align-items: center;
}css而 justify-content 现在调整的是纵向的主轴,即垂直方向的对齐方式。
.container {
display: flex;
flex-direction: column;
justify-content: center;
}css多行布局#
flex 自动换行#
给 flex 容器使用 flex-wrap 属性,可以控制 flex 元素是否自动换行。
flex-wrap 的默认值为 nowrap,当容器空间不足(比如手机屏幕,横向空间较小)时,会压扁(收缩)其中的元素。如果元素无法被压缩,会直接溢出容器。
.container {
display: flex;
gap: 40px;
flex-wrap: nowrap;
}css如果你正在使用电脑浏览这个页面,你可以试试拖动浏览器窗口右侧,改变页面宽度,观察下面的元素会发生什么。
将 flex-wrap 设为 wrap,元素会自动在空间不足时换行。
.container {
display: flex;
flex-wrap: wrap;
gap: 40px;
max-width: 400px; /* 限制宽度方便展示换行 */
}css多行布局下的对齐方式#
就像主轴上有 justify-content 属性一样,交叉轴上也有 align-content属性,它可以控制交叉轴上整体的对齐方式。
现在有以下示例,在一个 flex 容器中装了 9 个元素,让它们自动换行,现在不使用 gap。
.container {
display: flex;
flex-wrap: wrap;
max-width: 320px;
height:450px;
}cssalign-content 默认为 stretch,所以可以发现即使不使用 gap,元素在垂直方向上依然有间隙。
align-content 同样也有 start、end 和 center 取值,让元素整体在交叉轴上对齐。比如,下面使用 align-content: center 让元素在交叉轴上居中对齐。
.container {
/* ... */
align-content: center;
}css前面说过,align-items 也是用来调整交叉轴上的对齐方式的,那么它和 align-content 的区别是什么呢?
尝试用 align-items 替代 align-content:
.container {
/* ... */
align-items: center;
}css.container {
/* ... */
align-items: end;
}css.container {
/* ... */
align-items: start;
}css结合上面三个例子不难看出,align-items 控制的 start、end 和 center 让元素对齐了它们各自的交叉轴。
其实在 wrap 自动换行后,每一行(如果设置了纵向主轴则是列)元素都有它们自己独立的主轴和交叉轴。此时 align-items 调整的是各行元素在自身的交叉轴上的对齐方式,而 align-content 调整的是多行元素整体在交叉轴上的对齐方式。
所以,如果要将元素完全居中对齐,我们应该在 flex 容器上设置以下三个 center 值:
.container {
/* ... */
justify-content: center;
align-items: center;
align-content: center;
/* 这里适当添加 gap,看起来更美观 */
gap: 10px;
}css拉伸和收缩元素#
自动拉伸#
如果想要让元素自动拉伸以填满容器的剩余空间,可以使用 flex-grow 属性。
flex-grow 的默认值为 0,即禁用自动拉伸。
.item {
flex-grow: 0;
}css当 flex-grow 设为 1 时,元素将会自动拉伸以填满容器空间。注意 flex-grow 属性是加在 item 元素身上的,而不是 flex 容器上。
.item {
flex-grow: 1;
}css也可以指定拉伸其中某个元素,其他不拉伸,比如只在第二个元素上添加 flex-grow: 1。
.item {
flex-grow: 0;
}
#item-2 {
flex-grow: 1;
}css自动收缩#
flex 容器中的元素在空间不足时会自动收缩,自动收缩由 flex-shrink 属性控制,其默认值为 1,即:
.item {
flex-shrink: 1;
}css注意 flex-shrink 属性是加在元素身上的,而不是 flex 容器上。
如果要禁用自动压缩,可以设置 flex-shrink: 0。
.item {
flex-shrink: 0;
}css按比例拉伸或收缩#
在同时存在多个 item 时,flex-grow 和 flex-shrink 的数值是有意义的,通过给它们设置不同的值,可以实现按比例拉伸或收缩。
<div class="container">
<div class="item" style="flex-grow:1;">1</div>
<div class="item" style="flex-grow:3;">2</div>
<div class="item" style="flex-grow:5;">3</div>
</div>html这样每个元素被拉伸的空间比例为 1:3:5。注意:这并不是说元素占用的空间是 1:3:5,而是它们被拉伸的空间是按这个比例分配的。
按比例收缩同理,数值越大被压缩的越多。
<div class="container">
<div class="item" style="flex-shrink:1;">1</div>
<div class="item" style="flex-shrink:3;">2</div>
<div class="item" style="flex-shrink:5;">3</div>
</div>html