2031 字
10 分钟
CSS Grid 布局完全指南

CSS Grid 布局完全指南#

概述#

CSS Grid 布局是 CSS 中最强大的布局系统,它是一个二维网格系统,可以同时处理行和列,为复杂布局提供了完美的解决方案。

基础概念#

1. 网格容器与网格项#

/* 定义网格容器 */
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 100px 200px;
  gap: 20px;
}

/* 网格项自动放置 */
.grid-item {
  background-color: #f0f0f0;
  padding: 20px;
}

2. 显式网格与隐式网格#

.container {
  display: grid;
  /* 显式网格:明确定义的行和列 */
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 100px 100px;
  
  /* 隐式网格:自动创建的行和列 */
  grid-auto-columns: 100px;
  grid-auto-rows: 150px;
  grid-auto-flow: row; /* 或 column, dense */
}

核心属性详解#

1. 轨道定义#

.container {
  /* 固定大小 */
  grid-template-columns: 100px 200px 300px;
  
  /* 百分比 */
  grid-template-columns: 25% 50% 25%;
  
  /* fr 单位(分数单位) */
  grid-template-columns: 1fr 2fr 1fr;
  
  /* repeat() 函数 */
  grid-template-columns: repeat(4, 1fr);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  
  /* minmax() 函数 */
  grid-template-columns: minmax(100px, 1fr) minmax(200px, 2fr);
  
  /* auto 关键字 */
  grid-template-columns: auto 1fr auto;
}

2. 网格线命名#

.container {
  display: grid;
  grid-template-columns: 
    [sidebar-start] 200px 
    [sidebar-end content-start] 1fr 
    [content-end];
  grid-template-rows: 
    [header-start] 80px 
    [header-end main-start] auto 
    [main-end footer-start] 60px 
    [footer-end];
}

.header {
  grid-column: sidebar-start / content-end;
  grid-row: header-start / header-end;
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
  grid-row: main-start / main-end;
}

.content {
  grid-column: content-start / content-end;
  grid-row: main-start / main-end;
}

.footer {
  grid-column: sidebar-start / content-end;
  grid-row: footer-start / footer-end;
}

3. 网格项放置#

.item {
  /* 使用网格线编号 */
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 3;
  
  /* 简写形式 */
  grid-column: 1 / 3;
  grid-row: 1 / 3;
  
  /* span 关键字 */
  grid-column: 1 / span 2;
  grid-row: 1 / span 2;
  
  /* 使用命名的网格线 */
  grid-column: sidebar-start / content-end;
  
  /* grid-area 简写 */
  grid-area: 1 / 1 / 3 / 3; /* row-start / column-start / row-end / column-end */
}

4. 对齐方式#

.container {
  /* 容器内对齐 */
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
  place-items: <align-items> <justify-items>;
  
  /* 内容对齐 */
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;
  place-content: <align-content> <justify-content>;
}

.item {
  /* 单个项目对齐 */
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
  place-self: <align-self> <justify-self>;
}

实战案例#

1. 圣杯布局#

.holy-grail {
  display: grid;
  grid-template-areas:
    "header header header"
    "nav main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

/* 响应式调整 */
@media (max-width: 768px) {
  .holy-grail {
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
    grid-template-columns: 1fr;
    grid-template-rows: auto auto 1fr auto auto;
  }
}

2. 瀑布流布局#

.masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 10px; /* 控制行高基数 */
  gap: 15px;
}

.masonry-item {
  /* 根据内容高度跨越不同行数 */
  grid-row-end: span var(--span, 10);
}

/* 通过 JavaScript 或 CSS 自定义属性设置不同的跨度 */
.masonry-item:nth-child(3n) { --span: 15; }
.masonry-item:nth-child(3n+1) { --span: 20; }
.masonry-item:nth-child(3n+2) { --span: 25; }

3. 卡片网格#

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 30px;
  padding: 20px;
}

.card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.card-header {
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.card-body {
  padding: 20px;
}

.card-footer {
  padding: 15px 20px;
  background-color: #f8f9fa;
  border-top: 1px solid #e0e0e0;
}

4. 仪表盘布局#

.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar main";
  min-height: 100vh;
}

.dashboard-header {
  grid-area: header;
  background: white;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  align-items: center;
  padding: 0 30px;
}

.dashboard-sidebar {
  grid-area: sidebar;
  background: #1a202c;
  color: white;
  padding: 20px;
}

.dashboard-main {
  grid-area: main;
  padding: 30px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  align-content: start;
}

.widget {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.widget-large {
  grid-column: span 2;
}

@media (max-width: 1024px) {
  .dashboard {
    grid-template-columns: 1fr;
    grid-template-rows: 60px auto 1fr;
    grid-template-areas:
      "header"
      "sidebar"
      "main";
  }
  
  .widget-large {
    grid-column: 1;
  }
}

高级技巧#

1. 子网格(Subgrid)#

/* 注意:子网格支持仍在完善中 */
.parent-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

.child-grid {
  display: grid;
  grid-template-columns: subgrid; /* 继承父网格的列轨道 */
  grid-template-rows: subgrid;    /* 继承父网格的行轨道 */
  grid-column: span 2;           /* 跨越两列 */
}

2. 网格与 Flexbox 结合#

.combined-layout {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 30px;
}

.grid-section {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}

.flex-section {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.flex-item {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 6px;
}

3. 动画与过渡#

.animated-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  transition: grid-template-columns 0.3s ease;
}

.animated-grid:hover {
  grid-template-columns: repeat(4, 1fr);
}

.grid-item {
  transition: all 0.3s ease;
}

.grid-item:hover {
  transform: scale(1.05);
  z-index: 1;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}

4. 动态网格#

.dynamic-grid {
  display: grid;
  /* 使用 CSS 自定义属性 */
  --columns: 3;
  --gap: 20px;
  
  grid-template-columns: repeat(var(--columns), 1fr);
  gap: var(--gap);
}

/* 通过媒体查询或 JavaScript 动态调整 */
@media (max-width: 768px) {
  .dynamic-grid {
    --columns: 2;
    --gap: 15px;
  }
}

@media (max-width: 480px) {
  .dynamic-grid {
    --columns: 1;
    --gap: 10px;
  }
}

性能优化#

1. 减少重排#

/* 避免频繁改变网格结构 */
.stable-grid {
  display: grid;
  /* 一次性定义好网格结构 */
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: auto;
}

/* 使用 grid-area 而不是频繁改变 grid-column/grid-row */
.grid-item {
  grid-area: var(--area);
}

/* 通过改变自定义属性来移动项目 */
.grid-item.active {
  --area: 1 / 1 / 3 / 4;
}

2. 合理使用 auto-fit 和 auto-fill#

/* auto-fit:尽可能填充可用空间 */
.auto-fit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  /* 当项目数量不足时,会拉伸项目填充空间 */
}

/* auto-fill:创建尽可能多的轨道 */
.auto-fill-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  /* 即使项目数量不足,也会创建空轨道 */
}

/* 根据需求选择 */
/* 需要填充空间时用 auto-fit */
/* 需要固定网格结构时用 auto-fill */

3. 避免过度嵌套#

/* 不好的做法:过度嵌套网格 */
.over-nested {
  display: grid;
}

.over-nested > div {
  display: grid;
}

.over-nested > div > div {
  display: grid;
}

/* 好的做法:使用单个网格 */
.flat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, auto);
}

/* 使用命名网格区域组织内容 */
.flat-grid {
  grid-template-areas:
    "header header header header"
    "sidebar main main aside"
    "footer footer footer footer";
}

浏览器支持与回退方案#

1. 特性检测#

/* 使用 @supports 进行特性检测 */
@supports (display: grid) {
  .modern-layout {
    display: grid;
    grid-template-columns: 1fr 300px;
  }
}

@supports not (display: grid) {
  .fallback-layout {
    display: flex;
    flex-wrap: wrap;
  }
  
  .fallback-layout > * {
    flex: 1 1 300px;
    margin: 10px;
  }
}

2. 渐进增强#

/* 基础布局(所有浏览器支持) */
.basic-layout {
  display: block;
}

.basic-layout > * {
  margin-bottom: 20px;
}

/* 增强布局(支持 Grid 的浏览器) */
@supports (display: grid) {
  .basic-layout {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
  }
  
  .basic-layout > * {
    margin-bottom: 0;
  }
}

工具与资源#

1. 开发工具#

  • Chrome DevTools:网格检查器
  • Firefox DevTools:网格调试工具
  • CSS Grid Generator:在线网格生成器

2. 学习资源#

  • MDN Web Docs:完整的 Grid 文档
  • CSS-Tricks:Grid 完全指南
  • Wes Bos:CSS Grid 免费课程

3. 实用代码片段#

/* 常用网格模式 */
.grid-patterns {
  /* 等宽网格 */
  &.equal-width {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
  
  /* 不对称网格 */
  &.asymmetric {
    grid-template-columns: 2fr 1fr 1fr;
  }
  
  /* 流式网格 */
  &.fluid {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  }
}

最佳实践#

1. 命名约定#

/* 使用有意义的网格线名称 */
.grid-container {
  grid-template-columns: 
    [full-start] minmax(20px, 1fr) 
    [main-start] minmax(0, 1200px) 
    [main-end] minmax(20px, 1fr) 
    [full-end];
}

/* 使用一致的间距单位 */
:root {
  --grid-gap: 20px;
  --grid-gap-small: 10px;
  --grid-gap-large: 30px;
}

.grid {
  gap: var(--grid-gap);
}

2. 响应式策略#

.responsive-grid {
  /* 移动端优先 */
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
  
  /* 平板 */
  @media (min-width: 768px) {
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
  }
  
  /* 桌面 */
  @media (min-width: 1024px) {
    grid-template-columns: repeat(3, 1fr);
    gap: 25px;
  }
  
  /* 大桌面 */
  @media (min-width: 1440px) {
    grid-template-columns: repeat(4, 1fr);
    gap: 30px;
  }
}

3. 可维护性#

/* 使用 CSS 自定义属性提高可维护性 */
:root {
  --grid-columns: 12;
  --grid-gutter: 20px;
  --container-width: 1200px;
}

.grid-system {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gutter);
  max-width: var(--container-width);
  margin: 0 auto;
}

/* 通过工具类快速应用网格 */
.col-1 { grid-column: span 1; }
.col-2 { grid-column: span 2; }
.col-3 { grid-column: span 3; }
/* ... 直到 col-12 */

.row-1 { grid-row: span 1; }
.row-2 { grid-row: span 2; }
/* ... */

总结#

CSS Grid 布局是现代 Web 开发的革命性技术,它提供了前所未有的布局控制能力。通过掌握 Grid 布局,你可以:

  1. 创建复杂布局:轻松实现传统布局方法难以完成的复杂设计
  2. 提高开发效率:减少布局相关的 CSS 代码量
  3. 增强响应式能力:更灵活地适应不同屏幕尺寸
  4. 改善代码维护:更清晰、更语义化的布局代码

随着浏览器支持的不断完善,CSS Grid 已经成为现代 Web 布局的首选方案。建议在实际项目中积极采用 Grid 布局,逐步替换传统的布局方法。


创建时间:2022-01-15 最后更新:2022-01-15 作者:前端开发团队 标签:CSS, Grid, 布局, 响应式设计, 前端开发

CSS Grid 布局完全指南
https://ameng404.com/posts/css/css-grid布局完全指南/
作者
Ameng
发布于
2022-01-15
许可协议
CC BY-NC-SA 4.0