讲解
Flexbox 是为一维布局设计的:一排(或一列)元素如何分配空间、如何对齐。给容器设 display: flex,它的直接子元素就成为「弹性项」(flex items),默认沿「主轴」水平排列。两个轴的概念是全部 API 的基础:主轴由 flex-direction 决定(row 水平、column 垂直),与之垂直的叫交叉轴。容器属性分两类:方向类 flex-direction、flex-wrap(wrap 允许换行,默认 nowrap 硬挤一行);对齐类 justify-content(沿主轴分配空间:flex-start、center、space-between、space-around、space-evenly)和 align-items(交叉轴对齐:stretch 默认拉伸、center、flex-start、baseline)。多行时用 align-content 分配行间空间。gap 属性设置项间距,取代了给每项写 margin 再处理首尾多余间距的老办法。
弹性项自己的属性控制「怎么分蛋糕」:flex-grow 按比例分配剩余空间(默认 0 不抢);flex-shrink 空间不足时按比例收缩(默认 1);flex-basis 是分配前的基准尺寸(默认 auto 即内容尺寸)。三者合成简写 flex: grow shrink basis,最常用的两个值:flex: 1(即 1 1 0%,几项等分剩余空间)和 flex: none(不伸不缩)。单项覆盖对齐用 align-self。还有个隐藏特性:弹性项的 margin: auto 会吸走对应方向的剩余空间,ml-auto(margin-left: auto)把菜单推到最右,就是导航栏右对齐的经典实现。
弹性项的默认最小尺寸是 min-width: auto——不会缩到比内容更小,长文本、长 URL 会把布局撑破,解法是给该项 min-width: 0(或 overflow: hidden)再配省略号。这是 Flexbox 实战第一大坑,务必记住。
示例
/* 导航栏:logo 在左,菜单在右,垂直居中 */
.navbar {
display: flex;
align-items: center; /* 交叉轴(垂直)居中 */
gap: 16px;
}
.navbar .menu {
margin-left: auto; /* 吸走左侧剩余空间,把菜单推到最右 */
display: flex;
gap: 24px;
}
/* 三项等分 + 允许换行的卡片墙 */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card-list .card {
flex: 1 1 240px; /* 基准 240px,空间够就长大,不够就换行收缩 */
min-width: 0; /* 允许收缩到内容以下,配合省略号 */
}
/* 垂直方向布局:footer 推到底部 */
.page {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.page main {
flex: 1; /* 内容区吃掉剩余空间,footer 自然沉底 */
}
常见坑
- justify-content 与 align-items 记反:justify 管主轴、align 管交叉轴;flex-direction 换成 column 后两者方向互换,居中突然不灵先检查方向。
- flex: 1 三栏不等宽:flex: 1 是 1 1 0%,基准为 0 时才是严格等分;若写成 flex-grow: 1 而 basis 还是 auto,内容多的项会更宽。
- 内容撑破弹性项:长文本不收缩是 min-width: auto 的默认行为,给该项 min-width: 0 再加 text-overflow 三板斧。
- 给弹性项手写 margin 做间距:首尾项的多余 margin 要额外处理,父容器一个 gap 属性全解决(现代浏览器全支持)。
- 在弹性项上纠结 vertical-align/text-align:弹性项的「对齐」走 align-items/align-self 和 margin: auto 体系,行内时代的 vertical-align 对弹性项无效。
小结
Flexbox 管一维:容器定方向与对齐(flex-direction/justify-content/align-items/gap),子项定分配(flex 简写、align-self、margin: auto);记住 min-width: 0 这个收缩开关。下一章用它实现几种最常见的页面布局。