Flex 和 Grid 有什么区别?一维布局、二维布局怎么选?

Flex 和 Grid 有什么区别?一维布局、二维布局怎么选?

Flex 主要沿一条主轴分配空间,适合导航、工具栏和一排需要伸缩的元素。即使换了行,各行也主要独立计算,不天然共享一套列轨道。

Grid 则先定义行列轨道,再把元素放进网格,适合需要跨行对齐、跨列占位的页面或卡片区域。

实际项目里,我会先看设计希望元素跟着内容走,还是跟着行列结构走。它们完全可以组合使用,例如外层用 Grid 排卡片,卡片内部用 Flex 排按钮。选好之后还要检查最小尺寸和长文本,避免看起来写了自适应,实际上内容把布局撑开。

一维和二维,不只是数页面有几行

工具栏为什么适合先考虑 Flex?

假设工具栏左边有标题和筛选按钮,右边有一个提交按钮。筛选文字有长有短,标题希望占剩余空间,提交按钮不想被挤成两行。

这时咱们关心的是,沿这一条横向主轴,谁使用固定空间,谁增长,空间不足时谁允许收缩。Flex 正好围绕这些问题工作。

flex-direction 决定主轴方向,justify-content 处理主轴上的对齐与剩余空间,align-items 处理交叉轴对齐。主轴可以是纵向,所以不要把 justify-content 直接背成"水平居中"。

Flex 换了行,为什么列不一定对齐?

把五张宽度随内容变化的卡片放进 flex-wrap, wrap 容器。第一行放三张,第二行放两张。若这些卡片允许增长,两行会各自分配剩余空间,第二行的两张可能明显更宽。

你当然可以给 Flex 子项固定宽度,让它们视觉上对齐。但那是你额外制定的尺寸规则,不是 Flex 自动维护了跨行列轨道。

如果设计要求第一列在每一行都使用同样的列边界,Grid 的共享轨道会更容易表达。一维布局也能出现多行,关键是这些行怎样共同决定尺寸。

Grid 先安排轨道,再放内容

假设页面要稳定显示三列卡片。可以先划三条等分轨道,并允许轨道在需要时收缩。

css 复制代码
.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 700px) {
  .cards { grid-template-columns: 1fr; }
}

minmax(0, 1fr) 的 0 是这里的最小轨道限制,不是把卡片内容宽度变成 0。内容仍需要处理换行。相比单写 1fr,它能避免某些自动最小尺寸把等分轨道撑大。

Grid 还可以让重点卡片跨两列,但视觉重排不要破坏键盘导航和阅读顺序。这里展示的是 CSS 原生布局,不提供不对应的 Python API。

别把布局工具当成二选一

外层卡片区用 Grid,卡片里的头像、名字和操作按钮用 Flex,是很自然的组合。反过来,纵向 Flex 页面也可以嵌一个 Grid 表单。

选择时先画元素之间需要保持的关系,跨行对齐、固定栏宽、按内容伸缩,还是简单间距。不要为了展示自己会 Grid,把两个按钮排成复杂网格;也不要为了只用 Flex,给二维区域堆很多难以维护的宽度计算。

验证时换成长标题、增加一个按钮、缩窄窗口,再用键盘走一遍。这几步比只看默认截图更能发现布局的问题。

本题机制参考,MDN,Flex 基础、MDN,Grid 基础。

面试官继续追问

flex, 1 一定代表三个元素等宽吗?

不能脱离最小尺寸和其他约束来保证。它常用于让元素按比例分配空间,但长内容、min-width、边框和其他 flex 设置都可能影响最终尺寸。

Grid 就不需要媒体查询了吗?

不一定。auto-fit 等方式能处理部分自适应,复杂布局仍可能需要断点来改变列数、区域或顺序。

order 能改变 DOM 顺序吗?

不能。它主要改变视觉排列,辅助技术和键盘访问仍受文档顺序等因素影响,因此不能用视觉排序修补不合理的 DOM。

面试速记卡

  • Flex,围绕一条主轴分配空间。
  • Flex 换行,各行主要独立处理,不天然共享列轨道。
  • Grid,用共享行列轨道安排位置和尺寸。
  • 选型,先看内容伸缩,还是行列对齐。
  • 工程实践,可以组合使用,长文本与键盘顺序都要检查。

我是程序员Sunday。本文收录于 sunday面试指南,原文与配图可继续阅读。

相关推荐
Csvn6 小时前
WASM
前端
利威尔xu7 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
修己xj7 小时前
我用 AI 给自己写了一个 Markdown 编辑器,然后把它开源了
前端
FRing037 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
幸运小猿7 小时前
模拟慢上传-处理超时重试image 丢失线上问题
前端·javascript·html
利威尔xu8 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
moshuying9 小时前
网购能买Token了!
前端
h_65432109 小时前
echarts实现柱状图加一条横线
前端·echarts
风骏时光牛马9 小时前
生成一个后端标题,只需要一个标题,不需要其他的任何文本。
前端
子非鱼@Itfuture9 小时前
关于前后端联调中登录状态/登录信息失效?
java·前端