Flexbox本身不是栅格系统,但可用其构建响应式栅格:核心是通过flex属性(flex-basis、flex-grow、flex-shrink)配合flex-wrap和媒体查询控制子项换行与宽度,而非硬编码列数;移动端优先设flex: 1 1 100%,再按需在断点中调整flex-basis,并用min-width防挤,兼顾兼容性与维护性。

Flexbox 本身不是栅格系统,但用它搭响应式栅格完全可行——关键不在“模仿 Bootstrap 的 .col-6”,而在控制 flex 行为 + 断点下的 flex-basis 切换。直接写死列数或依赖框架类名,反而容易在复杂嵌套中失控。
Flex 栅格的核心:用 flex 替代固定列宽计算
传统栅格靠百分比或 calc() 算宽度,Flex 栅格把列宽交给 flex 的三个参数控制。重点不是“几列”,而是“这一行最多放几个子项才换行”。
-
flex: 0 0 auto→ 子项不伸缩、不收缩、按内容宽 → 适合图标/按钮等固定尺寸组件 -
flex: 1 1 25%→ 允许伸缩,基础宽度占 25% → 四列布局起点,但会被媒体查询覆盖 -
flex: 1 1 100%→ 移动端默认单列,所有子项独占一行 - 配合
flex-wrap: wrap容器,子项超宽自动折行,比强制float或grid更容错
媒体查询断点怎么设才不重复写样式?
别按设备尺寸(如 @media (max-width: 768px))硬切,优先按容器内容撑开的实际需求设断点。比如一个卡片列表,在父容器 width 小于 600px 时双列就挤,那就用 @container(如果支持),否则退回到基于视口的断点,但只覆盖 flex-basis 和 flex-wrap,不动其他样式。
- 移动端优先:基础样式设
flex: 1 1 100%,再用@media (min-width: 768px)改为flex: 1 1 50% - 避免在每个断点里重写
justify-content或gap,这些应该抽到基础类里 - 慎用
max-width断点嵌套,比如@media (min-width: 768px) and (max-width: 1023px)—— 维护成本高,且和容器查询逻辑冲突
flex-wrap: wrap 配合 min-width 是防挤的关键
光靠 flex-basis 不够,当子项内容文字变长、图片加载失败或字体加载延迟时,flex 可能强行压缩导致文字溢出。加一层最小宽度兜底更稳。
立即学习“前端免费学习笔记(深入)”;
- 给子项设
min-width: 280px(常见卡片最小舒适宽度) - 容器保持
display: flex; flex-wrap: wrap; - 这样即使屏幕是 800px 宽,两个 280px 子项也放得下;到 500px 就自动变成一列,无需额外媒体查询
- 注意:
min-width值不能小于内容实际最小渲染宽度,否则无效
为什么不用 grid?什么时候该换?
Flex 栅格适合线性流式布局(如文章列表、导航栏、表单字段),Grid 更适合二维控制(如首页模块错位、图文混排、固定侧边栏)。但别因为“Grid 新”就硬上——grid 在老版 Safari(iOS 15.6 之前)对 subgrid 和部分函数支持差,而 Flex 的兼容性从 IE10+ 就稳定。
- 如果布局需要跨行对齐(比如标题和描述要严格左对齐,不管上面卡片高度)、或者要复用同一套模板适配不同数据密度,
grid-template-columns+auto-fit更干净 - 如果只是“在小屏堆成一列、中屏两列、大屏三列”,Flex + 媒体查询足够,代码量少、调试直观、回滚风险低
- 混合使用可以,但别让一个容器同时设
display: flex和display: grid—— 浏览器会忽略后者,容易误判
真正难的不是写对那几行 flex,而是判断哪些子项该参与弹性分配、哪些该固定尺寸、以及断点到底该响应“容器宽度”还是“视口宽度”。多数项目卡在这一步,而不是语法不会。


















