- 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: grid 或 display: 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% */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-column、grid-row 和 grid-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-area 是 grid-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";
}
}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: subgrid 或 grid-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 */
}
8. CSS Grid vs Flexbox:完整对比
Grid 和 Flexbox 不是竞争关系,而是互补关系。理解何时使用哪个是高级 CSS 的标志。
| 维度 | CSS Grid | Flexbox |
|---|---|---|
| 维度 | 二维(行 + 列) | 一维(行 或 列) |
| 适用场景 | 页面布局、复杂网格、仪表盘 | 导航栏、按钮组、居中元素 |
| 控制方式 | 主要从容器控制 | 容器和项目均可控制 |
| 内容适应 | 布局先行,内容填充网格 | 内容先行,项目适应空间 |
| 重叠元素 | 原生支持(同一网格区域) | 需要负 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; }
}display: grid激活二维布局;grid-template-columns/rows定义轨道fr单位分配剩余空间;repeat()避免重复轨道定义grid-template-areas创建可读的、可视化的布局定义minmax() + auto-fit是实现零媒体查询响应式网格的最佳方案auto-fit折叠空轨道(项目拉伸),auto-fill保留空轨道place-items: center是在网格单元中完美居中的快捷方式- Subgrid 解决跨卡片对齐问题(Chrome 117+, Firefox 71+, Safari 16+)
- 用 Grid 做页面结构,用 Flexbox 做组件内部布局——组合使用效果最佳
- CSS 自定义属性使网格系统可配置且易于主题化
- 浏览器 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-column 是 grid-column-start / grid-column-end 的简写,grid-row 是 grid-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: subgrid 或 grid-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-areas、minmax()、auto-fit 和 Subgrid 这些核心概念,你就能构建几乎任何布局——通常只需几行代码,而无需使用复杂的 hack 或过多的媒体查询。 配合 CSS 自定义属性和现代 DevTools,CSS Grid 让复杂布局的创建和维护变得前所未有的简单。
记住最重要的一点:Grid 用于页面结构,Flexbox 用于组件内部。将两者结合使用,你就拥有了构建任何现代 web UI 所需的全部工具。