返回博客列表
样式设计

CSS Grid 布局完全指南

2025-09-12
10 分钟阅读
CSS布局前端
CSS Grid 布局完全指南

CSS Grid 布局完全指南

CSS Grid 是现代 CSS 布局系统中最强大的工具之一。它提供了二维布局能力,让我们能够轻松创建复杂的网页布局。

什么是 CSS Grid?

CSS Grid 是一个二维布局系统,它允许我们同时控制行和列的布局。与 Flexbox 的一维布局不同,Grid 可以处理更复杂的布局需求。

Grid 的基本概念

  • Grid Container(网格容器):应用 display: grid 的元素
  • Grid Item(网格项):网格容器的直接子元素
  • Grid Line(网格线):构成网格的分界线
  • Grid Track(网格轨道):相邻网格线之间的空间
  • Grid Cell(网格单元格):相邻行线和列线之间的空间
  • Grid Area(网格区域):由四条网格线围成的区域

基础语法

创建网格容器

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 100px 100px;
  gap: 20px;
}

使用 fr 单位

.container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr; /* 中间列是两侧的两倍宽 */
  grid-template-rows: 100px 200px;
  gap: 20px;
}

使用 repeat() 函数

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 等同于 1fr 1fr 1fr */
  grid-template-rows: repeat(2, 100px);
  gap: 20px;
}

网格线命名

显式命名

.container {
  display: grid;
  grid-template-columns: [start] 1fr [middle] 1fr [end];
  grid-template-rows: [top] 100px [bottom];
}

隐式命名

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
}

/* 列线:1, 2, 3, 4 */
/* 行线:1, 2, 3 */

网格项定位

使用网格线定位

.item {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}

/* 简写形式 */
.item {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}

使用 span 关键字

.item {
  grid-column: 1 / span 2; /* 从第1列开始,跨越2列 */
  grid-row: 1 / span 1;     /* 从第1行开始,跨越1行 */
}

使用网格区域

.container {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "footer footer footer";
  grid-template-columns: 200px 1fr 1fr;
  grid-template-rows: 60px 1fr 60px;
}

.header {
  grid-area: header;
}

.sidebar {
  grid-area: sidebar;
}

.main {
  grid-area: main;
}

.footer {
  grid-area: footer;
}

响应式布局

使用 auto-fit 和 minmax

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

媒体查询

.container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

@media (min-width: 768px) {
  .container {
    grid-template-columns: 1fr 2fr;
  }
}

@media (min-width: 1024px) {
  .container {
    grid-template-columns: 1fr 2fr 1fr;
  }
}

实际应用示例

1. 卡片布局

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

.card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 20px;
}

2. 仪表板布局

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

.header {
  grid-area: header;
  background: #333;
  color: white;
  padding: 0 20px;
  display: flex;
  align-items: center;
}

.sidebar {
  grid-area: sidebar;
  background: #f5f5f5;
  padding: 20px;
}

.main {
  grid-area: main;
  background: white;
  padding: 20px;
}

.footer {
  grid-area: footer;
  background: #333;
  color: white;
  padding: 0 20px;
  display: flex;
  align-items: center;
}

3. 图片画廊

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

.gallery-item {
  overflow: hidden;
  border-radius: 8px;
}

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

/* 不同大小的图片 */
.gallery-item:nth-child(3n) {
  grid-row: span 2;
}

.gallery-item:nth-child(5n) {
  grid-column: span 2;
}

高级技巧

1. 子网格 (Subgrid)

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}

.child {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: span 2;
}

2. 网格对齐

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  justify-items: center;    /* 水平对齐 */
  align-items: center;      /* 垂直对齐 */
}

/* 单独控制某个项目 */
.item {
  justify-self: start;      /* 水平对齐 */
  align-self: end;          /* 垂直对齐 */
}

3. 网格流

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row;      /* 默认:按行填充 */
  /* grid-auto-flow: column; /* 按列填充 */
  /* grid-auto-flow: dense;  /* 密集填充 */
  gap: 20px;
}

与 Flexbox 的结合使用

Grid 用于整体布局,Flexbox 用于组件内部

.page {
  display: grid;
  grid-template-areas:
    "header"
    "main"
    "footer";
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header {
  grid-area: header;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
}

.main {
  grid-area: main;
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  gap: 20px;
  padding: 20px;
}

.footer {
  grid-area: footer;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

浏览器支持

CSS Grid 在现代浏览器中有很好的支持:

  • Chrome 57+
  • Firefox 52+
  • Safari 10.1+
  • Edge 16+

渐进增强

/* 基础布局(Flexbox 后备) */
.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex: 1 1 300px;
  margin: 10px;
}

/* Grid 增强 */
@supports (display: grid) {
  .container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
  }
  
  .item {
    margin: 0;
  }
}

最佳实践

1. 语义化命名

.layout {
  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;
}

2. 使用 CSS 自定义属性

:root {
  --grid-gap: 20px;
  --sidebar-width: 250px;
}

.layout {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  gap: var(--grid-gap);
}

3. 移动优先设计

/* 移动端:单列布局 */
.container {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

/* 平板:两列布局 */
@media (min-width: 768px) {
  .container {
    grid-template-columns: 1fr 1fr;
  }
}

/* 桌面:三列布局 */
@media (min-width: 1024px) {
  .container {
    grid-template-columns: 1fr 2fr 1fr;
  }
}

总结

CSS Grid 是一个强大的布局工具,它让我们能够创建复杂、响应式的网页布局。通过掌握 Grid 的基本概念和高级技巧,我们可以:

  • 创建复杂的二维布局
  • 实现响应式设计
  • 提高代码的可维护性
  • 减少对 JavaScript 布局库的依赖

记住,Grid 和 Flexbox 是互补的,不是竞争关系。Grid 用于整体布局,Flexbox 用于组件内部布局,两者结合使用能创造出最佳的布局效果。