DevToolBox免费
博客

CSS Grid指南:含Flexbox对比的完整布局教程

13 分钟阅读作者 DevToolBox
TL;DR
  • CSS Grid 是二维布局系统,Flexbox 是一维系统
  • fr 单位按比例分配剩余空间
  • grid-template-areas 创建可视化布局
  • minmax() + auto-fit 实现无媒体查询响应式
  • 子网格(Subgrid)解决跨卡片对齐问题
  • Grid + Flexbox 组合使用效果最佳

CSS Grid 布局是 CSS 中最强大的布局系统。它是一个二维网格系统,意味着它可以同时处理列和行。 与处理单一维度的 Flexbox 不同,Grid 让你能够构建复杂的网页布局,精确控制每个元素的放置位置。 本完整指南涵盖从基础概念到高级技术的一切内容,包括与 Flexbox 的对比、真实案例和调试技巧。

CSS Grid 于 2017 年在所有主流浏览器中获得原生支持,现已成为构建仪表盘、照片画廊、杂志风格页面、 定价表格和完整页面布局的首选方法。掌握 CSS Grid 是现代前端开发的核心技能。

1. CSS Grid 基础:启用网格布局

要创建网格容器,只需在父元素上设置 display: griddisplay: inline-grid。 所有直接子元素自动成为网格项目。

/* Block-level grid container */
.container {
  display: grid;
}

/* Inline grid container */
.container {
  display: inline-grid;
}

/* Children become grid items automatically */
.container > * {
  /* These are now grid items */
}

grid-template-columns 和 grid-template-rows

这两个属性定义网格轨道的数量和大小。你可以混合使用任何 CSS 长度单位、百分比,以及强大的 fr 分数单位。

/* Three equal columns */
.grid {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

/* Three columns: fixed, flexible, fixed */
.grid {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
}

/* Two rows: header 80px, content fills rest */
.grid {
  display: grid;
  grid-template-rows: 80px 1fr;
  height: 100vh;
}

/* Named grid lines for easier placement */
.grid {
  display: grid;
  grid-template-columns: [sidebar-start] 250px [sidebar-end content-start] 1fr [content-end];
}

fr 单位:分数空间

fr 单位代表网格容器中可用自由空间的一个分数。浏览器在分配固定尺寸轨道(px、em、%)后计算 fr 值。 这让你可以创建真正灵活的布局,无需计算百分比。

/* 1fr = all available space */
.grid { grid-template-columns: 1fr; }

/* Equal columns (each gets 1/3 of space) */
.grid { grid-template-columns: 1fr 1fr 1fr; }

/* Middle column is twice as wide */
.grid { grid-template-columns: 1fr 2fr 1fr; }

/* Mixed: fixed sidebar, flexible content */
.grid { grid-template-columns: 300px 1fr; }

/* Three equal columns + one double-width */
.grid { grid-template-columns: 1fr 1fr 2fr 1fr; }
/* Total: 5 parts — each 1fr = 20%, 2fr = 40% */
# grid-template-columns: 1fr 2fr 1fr 可视化
┌──────────┬────────────────────┬──────────┐
│ 1fr │ 2fr │ 1fr │
│ ~25% │ ~50% │ ~25% │
└──────────┴────────────────────┴──────────┘

repeat()

repeat() 函数可以避免重复写相同的轨道定义。第一个参数是重复次数(或关键词 auto-fill / auto-fit),第二个参数是轨道大小。

/* 3 equal columns — verbose */
.grid { grid-template-columns: 1fr 1fr 1fr; }

/* 3 equal columns — with repeat() */
.grid { grid-template-columns: repeat(3, 1fr); }

/* 12-column grid (like Bootstrap) */
.grid { grid-template-columns: repeat(12, 1fr); }

/* Mixed: 2 fixed sidebar + repeat columns */
.grid { grid-template-columns: 200px repeat(3, 1fr) 200px; }

/* Responsive: as many 200px columns as fit */
.grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

2. 网格放置:控制元素位置

默认情况下,网格项目按源顺序自动放置。但你可以使用 grid-columngrid-rowgrid-area 属性精确控制每个元素的位置和跨度。

grid-column & grid-row

/* grid-column: start / end (line numbers) */
.item {
  grid-column: 1 / 3;   /* spans columns 1 to 3 (2 columns wide) */
  grid-row: 1 / 2;      /* occupies row line 1 to 2 (1 row tall) */
}

/* Using span keyword */
.item {
  grid-column: 2 / span 2;  /* starts at line 2, spans 2 columns */
  grid-row: span 3;          /* spans 3 rows from auto-placed position */
}

/* Negative values count from the end */
.item {
  grid-column: 1 / -1;  /* full width across all columns */
  grid-row: 2 / -1;     /* from row 2 to the last row line */
}

/* Shorthand: grid-column is grid-column-start / grid-column-end */
.item { grid-column: 1 / 3; }
/* equivalent to: */
.item {
  grid-column-start: 1;
  grid-column-end: 3;
}

grid-area

grid-areagrid-row-start / grid-column-start / grid-row-end / grid-column-end 的简写,也可以引用命名模板区域中的名称。

/* Longhand equivalent */
.item {
  grid-area: 1 / 1 / 3 / 3;
  /* row-start=1, col-start=1, row-end=3, col-end=3 */
}

/* Named area reference (see grid-template-areas below) */
.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

3. 命名网格线和模板区域

grid-template-areas 是 CSS Grid 最直观的特性之一。它允许你使用字符串名称来定义布局,创建一种类似 ASCII 艺术的视觉布局表示。

/* Holy Grail layout with named areas */
.page {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 60px 1fr 50px;
  grid-template-areas:
    "header  header  header"
    "sidebar main    aside"
    "footer  footer  footer";
  min-height: 100vh;
}

/* Assign items to areas */
.page-header  { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main    { grid-area: main; }
.page-aside   { grid-area: aside; }
.page-footer  { grid-area: footer; }

/* Use period for empty cells */
.grid {
  grid-template-areas:
    "header header ."
    "sidebar main  main";
}

/* Responsive: collapse sidebar on mobile */
@media (max-width: 768px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "aside"
      "footer";
  }
}
# Holy Grail 布局可视化
┌────────────────────────────────────┐
│ HEADER (3 cols) │
├───────────┬────────────┬───────────┤
│ SIDEBAR │ MAIN │ ASIDE │
│ 200px │ 1fr │ 200px │
├───────────┴────────────┴───────────┤
│ FOOTER (3 cols) │
└────────────────────────────────────┘

4. 网格对齐:justify 和 align 属性

CSS Grid 提供了一套完整的对齐属性,分别作用于容器和单个项目。理解行轴(水平)和块轴(垂直)对于精通对齐至关重要。

/* ─── Container-level alignment ─── */

/* justify-items: aligns items along inline (row) axis */
.grid {
  justify-items: start;    /* left-align all items */
  justify-items: end;      /* right-align all items */
  justify-items: center;   /* center all items */
  justify-items: stretch;  /* fill cell width (default) */
}

/* align-items: aligns items along block (column) axis */
.grid {
  align-items: start;      /* top-align all items */
  align-items: end;        /* bottom-align all items */
  align-items: center;     /* vertically center all items */
  align-items: stretch;    /* fill cell height (default) */
  align-items: baseline;   /* align by text baseline */
}

/* Shorthand: place-items = align-items / justify-items */
.grid {
  place-items: center;           /* center both axes */
  place-items: center stretch;   /* vertical center, horizontal stretch */
}

/* justify-content: distributes columns when grid is smaller than container */
.grid {
  justify-content: start | end | center | stretch |
                   space-between | space-around | space-evenly;
}

/* align-content: distributes rows when grid is smaller than container */
.grid {
  align-content: start | end | center | stretch |
                 space-between | space-around | space-evenly;
}

/* Shorthand: place-content = align-content / justify-content */
.grid { place-content: center; }

/* ─── Individual item alignment ─── */
.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
  place-self: center;  /* shorthand: align-self / justify-self */
}

gap (行列间距)

/* gap shorthand (row-gap / column-gap) */
.grid {
  gap: 16px;           /* same gap for rows and columns */
  gap: 20px 10px;      /* row-gap=20px, column-gap=10px */
}

/* Individual gap control */
.grid {
  row-gap: 24px;
  column-gap: 12px;
}

/* Old syntax (still works, but gap is preferred) */
.grid {
  grid-gap: 16px;
  grid-row-gap: 24px;
  grid-column-gap: 12px;
}

5. 自动放置:grid-auto-flow 和 minmax()

grid-auto-flow

当网格项目没有明确放置时,浏览器使用自动放置算法。grid-auto-flow 控制自动放置的方向和行为。

/* Default: fill row by row, then add new rows */
.grid { grid-auto-flow: row; }

/* Fill column by column, then add new columns */
.grid { grid-auto-flow: column; }

/* Dense packing: fill gaps left by large items */
.grid { grid-auto-flow: row dense; }
.grid { grid-auto-flow: dense; }  /* same as row dense */

/* Control size of auto-generated rows/columns */
.grid {
  grid-auto-rows: 100px;        /* fixed height for implicit rows */
  grid-auto-rows: minmax(100px, auto); /* min 100px, grow to fit */
  grid-auto-columns: 200px;
}

minmax()

minmax(min, max) 定义轨道的最小和最大尺寸范围。这是实现无媒体查询响应式网格的关键。

/* Column is at least 200px, can grow to fill space */
.grid {
  grid-template-columns: minmax(200px, 1fr);
}

/* Three columns: each at least 150px, at most equal thirds */
.grid {
  grid-template-columns: repeat(3, minmax(150px, 1fr));
}

/* Rows: at least 80px tall, expand for content */
.grid {
  grid-auto-rows: minmax(80px, auto);
}

/* The "holy grail" responsive card pattern */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 24px;
}
/* ↑ Creates as many 250px+ columns as fit, then stretches them equally */

auto-fill vs auto-fit

/* auto-fill: creates as many tracks as fit, keeps empty tracks */
.grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* auto-fit: creates as many tracks as fit, COLLAPSES empty tracks */
.grid {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

/* Difference is visible when items < available columns:

   Container: 900px, min-item: 200px → 4 potential columns

   auto-fill (3 items):
   ┌──────┬──────┬──────┬──────┐
   │  #1  │  #2  │  #3  │      │  ← empty column preserved
   └──────┴──────┴──────┴──────┘

   auto-fit (3 items):
   ┌────────────┬────────────┬────────────┐
   │     #1     │     #2     │     #3     │  ← empty column collapsed
   └────────────┴────────────┴────────────┘
*/

6. 响应式网格模式

无媒体查询的响应式卡片网格

/* Cards that automatically reflow at any screen size */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 24px;
  padding: 24px;
}

/* The min(100%, 300px) prevents overflow on very small screens:
   - On wide screens: columns are at least 300px, max 1fr
   - On narrow screens: min(100%, 300px) = 100% → single column */

杂志/Pinterest 风格布局

/* Masonry-like layout with varying row spans */
.magazine {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
  gap: 16px;
}

/* Items take different row amounts */
.magazine .featured   { grid-row: span 3; grid-column: span 2; }
.magazine .tall       { grid-row: span 2; }
.magazine .wide       { grid-column: span 2; }
.magazine .normal     { /* defaults: 1 row, 1 col */ }

仪表盘布局

/* Full dashboard with fixed sidebar */
.dashboard {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "nav     topbar"
    "nav     content";
  min-height: 100vh;
}

.dashboard-nav     { grid-area: nav; }
.dashboard-topbar  { grid-area: topbar; }
.dashboard-content { grid-area: content; }

/* Dashboard content with metric cards */
.dashboard-content {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto 1fr 1fr;
  gap: 20px;
  padding: 24px;
}

.metric-card    { /* 1 col × 1 row */ }
.chart-main     { grid-column: span 3; grid-row: span 2; }
.chart-side     { grid-row: span 2; }

@media (max-width: 1024px) {
  .dashboard-content {
    grid-template-columns: repeat(2, 1fr);
  }
  .chart-main { grid-column: span 2; }
}

@media (max-width: 768px) {
  .dashboard {
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "content";
  }
  .dashboard-nav { display: none; } /* or transform into drawer */
}

照片画廊布局

/* Auto-filling image gallery */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 200px;
  gap: 4px;
}

.gallery img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Feature every 5th image */
.gallery .feature {
  grid-column: span 2;
  grid-row: span 2;
}

/* Landscape portrait mix with dense packing */
.gallery { grid-auto-flow: dense; }
.landscape { grid-column: span 2; }
.portrait  { grid-row: span 2; }

定价表格布局

/* 3-column pricing table */
.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border-radius: 16px;
  overflow: hidden;
}

/* Highlight the middle (recommended) plan */
.pricing-grid .plan-featured {
  grid-row: 1 / -1;
  transform: scaleY(1.02);
  z-index: 1;
  box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}

@media (max-width: 768px) {
  .pricing-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .pricing-grid .plan-featured {
    transform: none;
    order: -1; /* show featured plan first on mobile */
  }
}

7. 子网格 (Subgrid) — CSS Grid Level 2

子网格(grid-template-columns: subgridgrid-template-rows: subgrid)允许嵌套的网格项目参与并继承其祖先网格的轨道尺寸。 这解决了长期存在的"跨卡片对齐"问题:让不同卡片内的子元素跨卡片边界对齐。 子网格在 Firefox 71、Chrome 117、Safari 16 中获得支持,截至 2023 年已在所有现代浏览器中可用。

/* PROBLEM: Card titles/descriptions don't align across cards */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.card { display: flex; flex-direction: column; }
/* ↑ Each card has its own layout context — no cross-card alignment */

/* SOLUTION: Subgrid for cross-card alignment */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto 1fr auto; /* img, title, body, button */
  gap: 20px 20px;
}

.card {
  display: grid;
  grid-row: span 4;           /* card spans 4 rows */
  grid-template-rows: subgrid; /* inherit row tracks from parent! */
}

/* Now .card-image, .card-title, .card-body, .card-button
   in ALL cards share the SAME row tracks → perfect alignment */
.card-image  { grid-row: 1; }
.card-title  { grid-row: 2; }
.card-body   { grid-row: 3; }
.card-button { grid-row: 4; }

/* Subgrid can be used for columns too */
.nested-grid {
  display: grid;
  grid-column: 2 / 5;
  grid-template-columns: subgrid; /* inherits 3 parent columns */
}
# Subgrid 解决跨卡片对齐
Without subgrid: With subgrid:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ [img] │ │ [img] │ │ [img] │ │ [img] │
│ Short │ │ A Very │ │ Short │ │ A Very │
│ Title │ │ Long │ │ Title │ │ Long │
│ Body... │ │ Title │ │ Body... │ │ Title │
│ [btn] │ │ Body... │ │ │ │ │
└──────────┘ │ [btn] │ │ [btn] │ │ Body... │
misaligned └──────────┘ └──────────┘ │ [btn] │
perfectly └──────────┘
aligned!

8. CSS Grid vs Flexbox:完整对比

Grid 和 Flexbox 不是竞争关系,而是互补关系。理解何时使用哪个是高级 CSS 的标志。

维度CSS GridFlexbox
维度二维(行 + 列)一维(行 或 列)
适用场景页面布局、复杂网格、仪表盘导航栏、按钮组、居中元素
控制方式主要从容器控制容器和项目均可控制
内容适应布局先行,内容填充网格内容先行,项目适应空间
重叠元素原生支持(同一网格区域)需要负 margin 或 position
轨道对齐强大(行和列对齐)单轴对齐
响应式设计自动放置 + minmax() 极其强大需要媒体查询控制换行
命名布局支持 grid-template-areas不支持
浏览器支持所有现代浏览器(2017+)所有现代浏览器(2012+)

何时选择 Grid

/* Use Grid for:
   ✓ Full-page layouts (header/sidebar/main/footer)
   ✓ Card grids with consistent row heights
   ✓ Dashboard interfaces with multiple panels
   ✓ Magazine-style layouts with varying cell sizes
   ✓ Any layout where rows AND columns matter simultaneously
   ✓ When you need items to span multiple tracks
   ✓ Named area layouts for clarity and responsiveness
*/

/* Classic Grid use case: */
.page-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 64px 1fr 48px;
  grid-template-areas:
    "sidebar header"
    "sidebar content"
    "sidebar footer";
  min-height: 100vh;
}

何时选择 Flexbox

/* Use Flexbox for:
   ✓ Navigation bars (horizontal list of links)
   ✓ Button groups and toolbars
   ✓ Centering a single element
   ✓ Card internals (icon + text layout)
   ✓ Form layouts with labels and inputs
   ✓ Any layout where items flow in one direction
   ✓ When content size should drive layout
*/

/* Classic Flexbox use case: */
.navbar {
  display: flex;
  align-items: center;
  gap: 16px;
}

.navbar .logo   { margin-right: auto; } /* push nav links to right */
.navbar .links  { display: flex; gap: 8px; }
.navbar .button { /* stays at far right */ }

最佳实践:Grid + Flexbox 组合

/* Use Grid for the outer page structure,
   Flexbox for inner component layouts */

/* OUTER: Grid layout */
.app {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar main";
  min-height: 100vh;
}

/* INNER: Flexbox components */
.header {
  grid-area: header;
  display: flex;          /* flex for navbar */
  align-items: center;
  padding: 0 24px;
  gap: 16px;
}

/* Even deeper: Grid card layout → Flexbox card content */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}

.card {
  display: flex;           /* flex for vertical card content */
  flex-direction: column;
}

.card-body { flex: 1; }   /* pushes footer to bottom */

9. CSS Grid 与 CSS 自定义属性

CSS 自定义属性(变量)与 CSS Grid 配合使用非常强大,可以创建可配置的、主题化的网格系统。

/* Define a configurable grid system */
:root {
  --grid-columns: 12;
  --grid-gap: 24px;
  --grid-max-width: 1200px;
  --sidebar-width: 280px;
  --card-min-width: 260px;
}

/* Base grid using variables */
.grid-container {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gap);
  max-width: var(--grid-max-width);
  margin: 0 auto;
}

/* Responsive overrides via custom properties */
@media (max-width: 1024px) {
  :root { --grid-columns: 8; --grid-gap: 16px; }
}

@media (max-width: 768px) {
  :root { --grid-columns: 4; --grid-gap: 12px; }
}

/* Theming: dark mode changes gap/sizing */
@media (prefers-color-scheme: dark) {
  :root { --grid-gap: 20px; }
}

/* Component-level overrides */
.hero-grid {
  --grid-columns: 2;
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gap);
}

/* Dynamic inline grid (controlled by JS or inline styles) */
.dynamic-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), 1fr);
}
/* In HTML: <div class="dynamic-grid" style="--cols: 4"> */

10. 浏览器支持与降级处理

CSS Grid 在所有现代浏览器中的支持率超过 97%(截至 2024 年)。对于需要支持旧版浏览器的项目,可以使用特性检测和优雅降级。

/* Browser support (caniuse.com as of 2024):
   Chrome 57+    ✓ (2017)
   Firefox 52+   ✓ (2017)
   Safari 10.1+  ✓ (2017)
   Edge 16+      ✓ (2017)
   IE 11         partial (old syntax, -ms- prefix)
   Global support: ~97%+ */

/* Progressive enhancement: Flexbox fallback → Grid enhancement */
.container {
  display: flex;          /* Flexbox for old browsers */
  flex-wrap: wrap;
}

@supports (display: grid) {
  .container {
    display: grid;        /* Grid for modern browsers */
    grid-template-columns: repeat(3, 1fr);
  }
}

/* @supports for specific Grid features */
@supports (grid-template-areas: "a") {
  /* Named areas supported */
}

@supports (grid-template-rows: subgrid) {
  /* Subgrid supported */
  .card {
    grid-template-rows: subgrid;
  }
}

/* IE 11 fallback with -ms- prefix */
.ie-compat {
  display: -ms-grid;
  -ms-grid-columns: 200px 1fr;
  -ms-grid-rows: 60px 1fr;
}

/* Modern equivalent */
.ie-compat {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: 60px 1fr;
}

11. 常见错误与调试技巧

常见错误

/* MISTAKE 1: Setting display:grid on items (not container) */
.item { display: grid; } /* Wrong: this creates a new grid context */
.container { display: grid; } /* Correct */

/* MISTAKE 2: Forgetting grid-template-columns defaults to single column */
.container { display: grid; }
/* ↑ All items stack vertically — add grid-template-columns! */
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* Now 3 columns */
}

/* MISTAKE 3: gap vs padding confusion */
.container { gap: 20px; }  /* Space between items */
.container { padding: 20px; } /* Space inside container (not between items) */

/* MISTAKE 4: Forgetting grid-column/row auto-placement resets */
/* When you explicitly place some items, auto-placed items fill remaining cells */

/* MISTAKE 5: Using % width on grid items (usually wrong) */
.item { width: 33%; } /* Wrong: grid already controls width via fr */
.item { } /* Correct: let grid track sizing do the work */

/* MISTAKE 6: grid-gap (old) vs gap (new) */
.grid { grid-gap: 16px; }  /* Old — still works but deprecated */
.grid { gap: 16px; }       /* Modern — preferred */

/* MISTAKE 7: Overlapping items without z-index */
.item-1 { grid-area: 1 / 1 / 3 / 3; }
.item-2 { grid-area: 2 / 2 / 4 / 4; } /* overlaps item-1 */
/* Add z-index to control stacking: */
.item-1 { z-index: 1; }
.item-2 { z-index: 2; }

调试技巧

/* TIP 1: Visualize grid with outline */
.container > * {
  outline: 2px solid red;
}

/* TIP 2: Background color different cells */
.item:nth-child(odd)  { background: rgba(100, 200, 255, 0.2); }
.item:nth-child(even) { background: rgba(255, 150, 100, 0.2); }

/* TIP 3: DevTools Grid Inspector
   - Firefox: Elements → grid badge → Layout panel
   - Chrome: Elements → grid badge → Layout panel
   Shows: line numbers, track sizes, area names, gaps */

/* TIP 4: Temporarily add grid-template-rows to see all rows */
.debug {
  grid-template-rows: 50px 50px 50px; /* see row boundaries */
}

/* TIP 5: Use grid-template-areas to debug layout visually */
.debug {
  grid-template-areas:
    "A A B"
    "C D B"
    "C E E";
  /* Every letter is a named area — easy to visualize */
}

12. 真实案例:完整仪表盘 + 定价页面

完整仪表盘 HTML + CSS

/* ═══════════════════════════════════
   Complete Dashboard Grid Layout
   ═══════════════════════════════════ */

/* 1. App Shell */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-width, 240px) 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "sidebar topbar"
    "sidebar content";
  height: 100vh;
  overflow: hidden;
}

/* 2. Sidebar: flex column internally */
.sidebar {
  grid-area: sidebar;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

/* 3. Top Bar: flex row */
.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
}

/* 4. Content area: nested grid */
.content {
  grid-area: content;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto;
  grid-auto-rows: minmax(120px, auto);
  gap: 20px;
  padding: 24px;
  overflow-y: auto;
  align-content: start;
}

/* 5. KPI metric cards */
.metric-card { /* default: 1×1 */ }

/* 6. Main chart: spans 3 columns × 2 rows */
.chart-primary {
  grid-column: span 3;
  grid-row: span 2;
}

/* 7. Activity feed: 1 col × 2 rows */
.activity-feed {
  grid-row: span 2;
}

/* 8. Wide table: full width */
.data-table {
  grid-column: 1 / -1;
}
<!-- Dashboard HTML Structure -->
<div class="app">
  <nav class="sidebar">...</nav>
  <header class="topbar">...</header>
  <main class="content">
    <div class="metric-card">Revenue</div>
    <div class="metric-card">Users</div>
    <div class="metric-card">Orders</div>
    <div class="metric-card">Churn</div>
    <div class="chart-primary">Main Chart</div>
    <div class="activity-feed">Activity</div>
    <div class="data-table">Data Table</div>
  </main>
</div>

响应式定价表格

/* Three-tier pricing: Starter / Pro / Enterprise */
.pricing {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  background: #e2e8f0;
  border-radius: 16px;
  overflow: hidden;
  max-width: 900px;
  margin: 0 auto;
}

.pricing-plan {
  background: #fff;
  padding: 40px 32px;
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  gap: 16px;
}

.pricing-plan.featured {
  background: #1e293b;
  color: #f8fafc;
  transform: scaleY(1.02);
  z-index: 1;
}

.plan-name    { font-size: 20px; font-weight: 700; }
.plan-price   { font-size: 48px; font-weight: 800; }
.plan-period  { font-size: 14px; opacity: 0.6; }
.plan-features{ /* fills remaining space */ }
.plan-cta     { /* sticks to bottom */ }

@media (max-width: 768px) {
  .pricing {
    grid-template-columns: 1fr;
    gap: 16px;
    background: transparent;
  }
  .pricing-plan.featured {
    transform: none;
    order: -1;
    border-radius: 12px;
  }
  .pricing-plan { border-radius: 12px; }
}
Key Takeaways — 核心要点
  1. display: grid 激活二维布局;grid-template-columns/rows 定义轨道
  2. fr 单位分配剩余空间;repeat() 避免重复轨道定义
  3. grid-template-areas 创建可读的、可视化的布局定义
  4. minmax() + auto-fit 是实现零媒体查询响应式网格的最佳方案
  5. auto-fit 折叠空轨道(项目拉伸),auto-fill 保留空轨道
  6. place-items: center 是在网格单元中完美居中的快捷方式
  7. Subgrid 解决跨卡片对齐问题(Chrome 117+, Firefox 71+, Safari 16+)
  8. 用 Grid 做页面结构,用 Flexbox 做组件内部布局——组合使用效果最佳
  9. CSS 自定义属性使网格系统可配置且易于主题化
  10. 浏览器 DevTools 的 Grid 检查器是调试网格的最佳工具

常见问题 (FAQ)

CSS Grid 是什么?什么时候应该使用它?

CSS Grid 是 CSS 中的二维布局系统。当你需要同时控制行和列时使用它——例如完整页面布局、仪表盘、照片画廊和杂志风格设计。与 Flexbox(一维)不同,Grid 让你可以同时在两个方向上精确放置元素。

CSS Grid 中的 fr 单位是什么意思?

fr(fraction,分数)单位代表网格容器中可用自由空间的一个分数。例如,grid-template-columns: 1fr 2fr 1fr 创建三列,中间列是外侧列的两倍宽。浏览器在分配固定尺寸轨道(px、em、%)后计算 fr 值。

CSS Grid 中 auto-fill 和 auto-fit 有什么区别?

两者都会创建尽可能多的适合容器的轨道。区别在于项目数量少于可用列数时:auto-fill 保留空轨道,维持其空间;auto-fit 将空轨道折叠为零宽度,允许项目拉伸填满容器。响应式卡片网格用 auto-fit,需要保持固定列数时用 auto-fill

grid-column 和 grid-row 简写属性如何工作?

grid-columngrid-column-start / grid-column-end 的简写,grid-rowgrid-row-start / grid-row-end 的简写。可以使用行号(grid-column: 1 / 3)、命名行或 span 关键词(grid-column: span 2)。负值从显式网格末尾开始计数,所以 grid-column: 1 / -1 跨越全部宽度。

CSS Grid 命名模板区域是什么?

命名模板区域通过在容器上使用 grid-template-areas 为网格单元分配字符串名称,然后在项目上用 grid-area 引用这些名称。这在 CSS 中创建了一个类似 ASCII 艺术的布局视觉表示。用句点(.)表示空单元。命名区域必须是矩形的,不能在非相邻单元中重复。

CSS Grid Level 2 中的 Subgrid 是什么?

Subgrid(grid-template-columns: subgridgrid-template-rows: subgrid)允许嵌套网格项目参与并继承其祖先网格的轨道尺寸。这解决了经典的"卡片对齐"问题:不同卡片内的子元素需要跨卡片边界对齐。自 2023 年起,所有现代浏览器均已支持 Subgrid。

我应该用 CSS Grid 还是 Flexbox?

当你需要同时控制行和列的二维布局时(页面布局、仪表盘、画廊)用 Grid。当元素沿单一方向流动时(导航栏、按钮组、居中)用 Flexbox。它们相辅相成——基于 Grid 的页面布局搭配基于 Flexbox 的组件是最常见也最有效的组合。

如何调试 CSS Grid 布局?

Chrome、Firefox 和 Edge 的 DevTools 都有专用的 CSS Grid 检查器。在 Firefox 中,点击 Elements 面板中容器旁的 grid 徽章可切换网格叠加层。在 Chrome 中,使用 Layout 面板查看网格行号和区域名称。最常用的调试技巧是为网格项目添加 outline: 1px solid red 或使用背景色来可视化每个单元格。

总结

CSS Grid 是现代 web 布局的基础。掌握 fr 单位、grid-template-areasminmax()auto-fit 和 Subgrid 这些核心概念,你就能构建几乎任何布局——通常只需几行代码,而无需使用复杂的 hack 或过多的媒体查询。 配合 CSS 自定义属性和现代 DevTools,CSS Grid 让复杂布局的创建和维护变得前所未有的简单。

记住最重要的一点:Grid 用于页面结构,Flexbox 用于组件内部。将两者结合使用,你就拥有了构建任何现代 web UI 所需的全部工具。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

🌈CSS Gradient Generator🎨Color ConverterMDMarkdown to HTML

相关文章

React Hooks 完全指南:useState、useEffect 和自定义 Hooks

通过实际示例掌握 React Hooks。学习 useState、useEffect、useContext、useReducer、useMemo、useCallback、自定义 Hooks 和 React 18+ 并发 Hooks。

Next.js性能优化:Core Web Vitals、缓存和边缘计算

掌握Next.js性能优化。含Core Web Vitals、图像/字体优化、代码分割、服务端组件、缓存策略、Bundle分析、ISR、Edge Runtime和数据库优化完整指南。

Web 性能优化:2026 Core Web Vitals 指南

全面的 Web 性能优化和 Core Web Vitals 指南。学习如何通过图片、JavaScript、CSS 和缓存的实用技术改善 LCP、INP 和 CLS。