Flexbox 与 Grid 的取舍:什么时候用哪个
Flexbox 和 Grid 经常被当成二选一的方案,其实它们的定位很清晰:Flex 处理一维(一行或一列)的分配,Grid 处理二维(行列同时约束)的编排。
判断标准:约束来自谁
问一个问题:布局的尺寸是由内容决定的,还是由容器决定的?
- 工具栏、导航、按钮组、卡片内部——尺寸由内容撑开,用 Flex。
- 页面骨架、仪表盘、图片墙——行列都要对齐,用 Grid。
/* 一维:内容决定宽度,剩余空间自动分配 */
.toolbar { display: flex; align-items: center; gap: 12px; }
.toolbar .spacer { flex: 1; }
/* 二维:容器决定列宽,子项自动填充 */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
}
flex: 1 到底等于什么
flex: 1 是 flex: 1 1 0% 的简写,注意基准值是 0% 而不是 auto。这意味着它忽略内容宽度,完全按比例分配剩余空间。
如果希望「内容优先,剩余再分配」,要写 flex: 1 1 auto。很多「文字被挤没了」的问题都源于此。
另外 min-width: auto 是 flex 子项的默认值,它会让子项无法收缩到内容宽度以下。要做省略号效果,必须显式覆盖:
.title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
Grid 的隐式轨道陷阱
只写了 grid-template-columns 时,行是隐式的,高度由内容决定。若要控制隐式行高,用 grid-auto-rows。另一个常见问题是 1fr 被长内容撑破——1fr 实际是 minmax(auto, 1fr),最小尺寸仍是内容宽度。安全写法是 minmax(0, 1fr)。
混用才是常态
真实页面里两者经常嵌套:Grid 排页面骨架,每个卡片内部用 Flex 排列标题与操作按钮。判断标准始终是「这一层的约束是单向还是双向」,而不是「哪个更新」。
最后提醒一点:gap 在两个布局里语义一致,能替代大量 margin 计算。早期为了兼容而写的 margin-right 加 :last-child 清零,现在可以直接删掉了。