Flex 与 Grid 使用技巧 & 注意点

Flex 与 Grid 使用技巧 & 注意点

一份面向实战的 CSS 布局速查 —— 何时用 Flex、何时用 Grid、常见坑与最佳实践


一、心智模型:先选对工具

维度 Flexbox Grid
维度 一维(行 或 列) 二维(行 和 列)
思路 内容驱动(让子项自适应) 布局驱动(先画格子,再放内容)
典型场景 导航栏、按钮组、卡片内部、表单行 页面级布局、仪表盘、瀑布流、复杂表格
子项控制权 子项 (flex-grow/shrink/basis) 容器 (grid-template-*)

一句话决策

  • 一行/一列排列 → Flex
  • 同时要管行又管列 → Grid
  • 复杂卡片:外层 Grid + 内层 Flex(最常见组合)

二、Flexbox 实战技巧

1. 常用容器属性速查

.container {
  display: flex; /* 或 inline-flex */
  flex-direction: row | column; /* 主轴方向 */
  flex-wrap: wrap; /* 默认 nowrap,移动端必加 */
  justify-content: space-between; /* 主轴对齐 */
  align-items: center; /* 交叉轴对齐(单行) */
  align-content: center; /* 交叉轴对齐(多行) */
  gap: 12px 8px; /* 行间距 列间距 */
}

2. 子项控制三件套

.item {
  flex: 1 1 auto;
  /* ↑ 等价于:flex-grow flex-shrink flex-basis */
}
简写 等价 用途
flex: 1 1 1 0% 平均分配剩余空间(最常用)
flex: auto 1 1 auto 按内容大小分配
flex: none 0 0 auto 不伸不缩(固定宽度侧边栏)
flex: 0 0 200px 固定 200px 宽

3. 经典模式

/* ✅ 圣杯布局:左侧栏固定 + 右侧自适应 */
.layout {
  display: flex;
}
.sidebar {
  flex: 0 0 240px;
}
.main {
  flex: 1;
  min-width: 0;
} /* min-width: 0 关键! */

/* ✅ 垂直水平居中(一行搞定) */
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* ✅ 等高卡片 */
.cards {
  display: flex;
} /* 默认 align-items: stretch */

/* ✅ 底部对齐按钮 */
.card {
  display: flex;
  flex-direction: column;
}
.card-footer {
  margin-top: auto;
} /* 神技 */

4. ⚠️ Flex 高频坑

现象 解法
文字溢出撑破容器 子项有长文本时 flex: 1 撑爆 子项加 min-width: 0(或 overflow: hidden
flex-basis vs width 同时设置时优先级混乱 flex-basis 别用 width(更语义化)
gap 兼容性 老 Safari 不支持 降级用 margin 或加 :not(:last-child)
flex-shrink 默认 1 图片被压缩变形 img { flex-shrink: 0; }
align-items: stretch 撑高图片 img 被拉伸 父级 align-items: flex-start 或 img 包一层 div
百分比 margin Flex 容器中 margin-top: 50% 不基于父高 用 transform 或绝对定位

5. 高级技巧

/* margin: auto 在 Flex 中是"占据剩余空间" */
.nav-right {
  margin-left: auto;
} /* 推到最右边,不用 justify-content */

/* 反向排列但保留 tab 顺序 */
.reverse {
  flex-direction: row-reverse;
}

/* order 重排(不影响 DOM 顺序,无障碍友好) */
.first {
  order: -1;
}

三、Grid 实战技巧

1. 容器属性速查

.grid {
  display: grid;
  grid-template-columns: 200px 1fr 1fr; /* 3 列 */
  grid-template-rows: auto 1fr auto; /* 3 行 */
  gap: 16px; /* 等于 row-gap + column-gap */

  /* 命名区域(最强可读性) */
  grid-template-areas:
    "header header header"
    "side   main   main"
    "footer footer footer";
}

2. 必学单位与函数

工具 用途 示例
fr 分配剩余空间 1fr 2fr 1fr
minmax(min, max) 限制范围 minmax(200px, 1fr)
repeat() 重复 repeat(3, 1fr)
auto-fill 自动填满,保留空轨道 repeat(auto-fill, minmax(200px, 1fr))
auto-fit 自动填满,折叠空轨道 卡片少时撑满整行

3. 神级一行:响应式卡片网格

/* 屏幕宽自动放 N 列,每列至少 240px */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}
/* 不需要任何媒体查询! */

4. 子项定位

/* 方式 1:行列线 */
.item {
  grid-column: 1 / 3; /* 从第 1 条线到第 3 条线 */
  grid-row: 2 / span 2; /* 跨 2 行 */
}

/* 方式 2:命名区域(推荐) */
.header {
  grid-area: header;
}
.main {
  grid-area: main;
}

/* 方式 3:负数索引(从末尾算) */
.last {
  grid-column: -2 / -1;
}

5. 对齐三件套(Grid 比 Flex 更强)

/* 容器层 */
justify-items: center; /* 子项在格子内水平对齐 */
align-items: center; /* 子项在格子内垂直对齐 */
place-items: center; /* 上面两个的简写 */

justify-content: center; /* 整个网格在容器内水平对齐 */
align-content: center; /* 整个网格在容器内垂直对齐 */
place-content: center;

/* 子项层(可单独覆盖) */
.item {
  justify-self: end;
  align-self: start;
}

6. 经典模式

/* ✅ 圣杯布局(命名区域版,秒懂) */
.layout {
  display: grid;
  grid-template:
    "header header" auto
    "side   main" 1fr
    "footer footer" auto
    / 240px 1fr;
}

/* ✅ 表单:左侧 label 右侧 input 自动对齐 */
.form {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: center;
}

/* ✅ 子项重叠(Grid 独有!) */
.stack > * {
  grid-area: 1 / 1;
} /* 全部叠在同一格 */

7. ⚠️ Grid 高频坑

现象 解法
隐式行高失控 没设 grid-template-rows,行高被内容撑爆 显式定义 grid-auto-rows: minmax(100px, auto)
fr 与 content 冲突 1fr 列被超长文本撑大 minmax(0, 1fr) 替代 1fr
subgrid 兼容性 老浏览器不支持 Firefox 全支持,Chrome 117+,按需降级
gap 计入 fr 计算 算出来的列宽和预期不符 gap 是从总宽度先扣除再分配
auto-fill vs auto-fit 空轨道是否塌缩 卡片少又想撑满 → auto-fit;保留占位 → auto-fill
z-index 失效 Grid 子项需要 position: relative 加上即可

四、Flex vs Grid 对比决策表

需求 推荐 原因
导航栏 Flex 一维排列,需要 margin-left: auto
按钮组 Flex gap + align-items 够用
卡片列表(自适应列数) Grid auto-fill + minmax 无媒体查询
仪表盘 Grid 二维布局,命名区域可读性强
表单(label + input) Grid auto 1fr 自动对齐
元素重叠(如徽章) Grid grid-area: 1/1 比绝对定位优雅
聊天气泡 Flex 一列,按 align-self 左右切换
后台 Layout(顶部+侧栏+主内容) Grid 一次性画清结构
居中 Flex 三行代码秒中

五、组合使用范式(实战标配)

<!-- 外层 Grid 管页面 → 内层 Flex 管组件 -->
<div class="page">
  <!-- Grid -->
  <header class="navbar"><!-- Flex --></header>
  <aside class="sidebar"></aside>
  <main class="content">
    <!-- Grid 卡片墙 -->
    <article class="card"><!-- Flex 列 --></article>
  </main>
</div>
.page {
  display: grid;
  grid-template: "nav nav" auto "side main" 1fr / 240px 1fr;
  min-height: 100vh;
}
.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.content {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}
.card {
  display: flex;
  flex-direction: column;
}
.card-footer {
  margin-top: auto;
}

六、性能与可维护性建议

  1. 优先用现代特性gap 替代 margin 间距;place-items 替代多行对齐
  2. 响应式优先 Gridauto-fill + minmax 比媒体查询断点更优雅
  3. 避免过度嵌套 Flex:超过 3 层考虑换 Grid
  4. min-width: 0 / min-height: 0 是 Flex/Grid 子项的"隐藏开关",记牢
  5. 命名区域 > 行列线数字:可读性、可维护性碾压
  6. Subgrid(Chrome 117+)让嵌套 Grid 对齐父网格,复杂表单/表格神器
  7. 避免动画 width/height:用 transform: scale(),Flex/Grid 重排成本高
  8. DevTools 用起来:Chrome 的 Grid/Flex Overlay 可视化调试

七、速记

Flex 一维、Grid 二维Flex 内容驱动、Grid 布局驱动
导航栏卡片内部用 Flex,页面级布局和卡片墙用 Grid
gap 是新时代的 marginmin-width: 0 是 Flex 子项的救命符
repeat(auto-fill, minmax(240px, 1fr)) 是响应式神咒
外层 Grid + 内层 Flex 是中后台最常见组合


八、参考资源

posted @ 2026-05-26 15:50  HuangBingQuan  阅读(19)  评论(0)    收藏  举报