Grid 网格布局

CSS Grid 布局的基本用法和常见场景

问题

掌握 CSS Grid 网格布局的基本概念和常用属性。

解答

基本概念

Grid 布局将容器划分为行和列,形成单元格,然后将项目放置到单元格中。

.container {
  display: grid;
}

定义行和列

.container {
  display: grid;
  /* 定义 3 列,每列 200px */
  grid-template-columns: 200px 200px 200px;
  /* 定义 2 行,每行 100px */
  grid-template-rows: 100px 100px;
  /* 行列间距 */
  gap: 10px;
}

常用单位和函数

.container {
  display: grid;
  /* fr 单位:按比例分配剩余空间 */
  grid-template-columns: 1fr 2fr 1fr;
  
  /* repeat() 函数:重复定义 */
  grid-template-columns: repeat(3, 1fr);
  
  /* auto-fill:自动填充 */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  
  /* minmax():设置最小和最大值 */
  grid-template-columns: minmax(100px, 1fr) 2fr;
}

项目定位

.item {
  /* 指定起始和结束的网格线 */
  grid-column: 1 / 3;  /* 从第 1 条列线到第 3 条列线 */
  grid-row: 1 / 2;     /* 从第 1 条行线到第 2 条行线 */
  
  /* 简写:跨越 2 列 */
  grid-column: span 2;
}

对齐方式

.container {
  display: grid;
  /* 整体内容对齐 */
  justify-content: center;  /* 水平方向 */
  align-content: center;    /* 垂直方向 */
  
  /* 所有项目在单元格内对齐 */
  justify-items: center;    /* 水平方向 */
  align-items: center;      /* 垂直方向 */
}

.item {
  /* 单个项目在单元格内对齐 */
  justify-self: end;
  align-self: start;
}

完整示例:响应式卡片布局

<!DOCTYPE html>
<html>
<head>
  <style>
    .card-grid {
      display: grid;
      /* 自动填充,每列最小 250px,最大 1fr */
      grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
      gap: 20px;
      padding: 20px;
    }
    
    .card {
      background: #f5f5f5;
      padding: 20px;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <div class="card-grid">
    <div class="card">卡片 1</div>
    <div class="card">卡片 2</div>
    <div class="card">卡片 3</div>
    <div class="card">卡片 4</div>
    <div class="card">卡片 5</div>
    <div class="card">卡片 6</div>
  </div>
</body>
</html>

经典布局:圣杯布局

<!DOCTYPE html>
<html>
<head>
  <style>
    .layout {
      display: grid;
      grid-template-areas:
        "header header header"
        "nav    main   aside"
        "footer footer footer";
      grid-template-columns: 200px 1fr 200px;
      grid-template-rows: 60px 1fr 60px;
      min-height: 100vh;
      gap: 10px;
    }
    
    .header { grid-area: header; background: #e74c3c; }
    .nav    { grid-area: nav;    background: #3498db; }
    .main   { grid-area: main;   background: #ecf0f1; }
    .aside  { grid-area: aside;  background: #2ecc71; }
    .footer { grid-area: footer; background: #9b59b6; }
  </style>
</head>
<body>
  <div class="layout">
    <header class="header">Header</header>
    <nav class="nav">Nav</nav>
    <main class="main">Main</main>
    <aside class="aside">Aside</aside>
    <footer class="footer">Footer</footer>
  </div>
</body>
</html>

关键点

  • grid-template-columns/rows 定义网格的列宽和行高
  • fr 单位按比例分配剩余空间,repeat() 简化重复定义
  • grid-column/row 控制项目跨越的网格线范围
  • grid-template-areas 配合 grid-area 实现命名区域布局
  • auto-fill + minmax() 是响应式布局的常用组合