CSS grid

29 阅读7分钟

1. 容器属性 (Container Properties)

display

定义网格容器

css

.container {
  display: grid;        /* 块级网格 */
  display: inline-grid; /* 行内网格 */
}

grid-template-columns / grid-template-rows

定义网格轨道大小

css

.container {
  /* 固定宽度列 */
  grid-template-columns: 100px 200px 150px;
  
  /* 分数单位 fr */
  grid-template-columns: 1fr 2fr 1fr;
  
  /* 混合使用 */
  grid-template-columns: 200px 1fr 2fr 100px;
  
  /* 重复模式 */
  grid-template-columns: repeat(3, 1fr);
  grid-template-columns: repeat(2, 100px 200px); /* 100px 200px 100px 200px */
  
  /* 自动填充 */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  
  /* minmax 函数 */
  grid-template-columns: minmax(100px, 1fr) minmax(200px, 2fr);
  
  /* 行定义 */
  grid-template-rows: 100px auto 200px;
}

grid-template-areas

通过命名区域定义网格布局

css

.container {
  grid-template-columns: 1fr 2fr 1fr;
  grid-template-rows: 80px 1fr 100px;
  grid-template-areas: 
    "header header header"
    "sidebar main aside"
    "footer footer footer";
}

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

grid-template

grid-template-rows、grid-template-columns 和 grid-template-areas 的简写

css

.container {
  /* 语法: grid-template: rows / columns */
  grid-template: 
    "header header" 80px
    "sidebar main" 1fr
    "footer footer" 100px
    / 200px 1fr;
}

gap (grid-gap)

定义网格线之间的间距

css

.container {
  /* 简写 */
  gap: 20px;
  gap: 15px 30px; /* row-gap column-gap */
  
  /* 单独设置 */
  row-gap: 15px;
  column-gap: 30px;
}

justify-items

沿着行轴(水平方向)对齐网格项内的内容

css

.container {
  justify-items: start;     /* 左对齐 */
  justify-items: end;       /* 右对齐 */
  justify-items: center;    /* 居中对齐 */
  justify-items: stretch;   /* 拉伸填充(默认) */
}

align-items

沿着列轴(垂直方向)对齐网格项内的内容

css

.container {
  align-items: start;       /* 顶部对齐 */
  align-items: end;         /* 底部对齐 */
  align-items: center;      /* 居中对齐 */
  align-items: stretch;     /* 拉伸填充(默认) */
  align-items: baseline;    /* 基线对齐 */
}

place-items

align-items 和 justify-items 的简写

css

.container {
  place-items: center;           /* align-items justify-items */
  place-items: start end;        /* align-items justify-items */
}

justify-content

当网格总大小小于容器时,沿着行轴对齐整个网格

css

.container {
  width: 1000px;
  grid-template-columns: repeat(3, 200px); /* 总宽600px */
  
  justify-content: start;       /* 左对齐 */
  justify-content: end;         /* 右对齐 */
  justify-content: center;      /* 居中对齐 */
  justify-content: stretch;     /* 拉伸网格项 */
  justify-content: space-around;/* 均匀分布 */
  justify-content: space-between;/* 两端对齐 */
  justify-content: space-evenly;/* 完全均匀 */
}

align-content

当网格总大小小于容器时,沿着列轴对齐整个网格

css

.container {
  height: 600px;
  grid-template-rows: repeat(2, 150px); /* 总高300px */
  
  align-content: start;        /* 顶部对齐 */
  align-content: end;          /* 底部对齐 */
  align-content: center;       /* 居中对齐 */
  align-content: stretch;      /* 拉伸网格项 */
  align-content: space-around; /* 均匀分布 */
  align-content: space-between;/* 两端对齐 */
  align-content: space-evenly; /* 完全均匀 */
}

place-content

align-content 和 justify-content 的简写

css

.container {
  place-content: center;          /* align-content justify-content */
  place-content: space-between end; /* align-content justify-content */
}

grid-auto-columns / grid-auto-rows

定义隐式网格轨道的大小

css

.container {
  grid-template-columns: 100px 100px;
  grid-template-rows: 100px 100px;
  
  /* 隐式轨道大小 */
  grid-auto-columns: 150px;
  grid-auto-rows: 80px;
}

/* 当项目超出显式网格时,使用隐式轨道大小 */
.item-5 {
  grid-column: 5; /* 超出显式网格,使用 grid-auto-columns */
}

grid-auto-flow

控制自动放置算法

css

.container {
  grid-auto-flow: row;        /* 按行填充(默认) */
  grid-auto-flow: column;     /* 按列填充 */
  grid-auto-flow: dense;      /* 密集填充,尝试填充空白 */
  grid-auto-flow: row dense;  /* 按行密集填充 */
}

grid

所有网格属性的简写

css

.container {
  /* 语法: grid-template-rows / grid-template-columns */
  grid: 100px 1fr / 200px 1fr;
  
  /* 包含 grid-template-areas */
  grid: 
    "header header" 80px
    "sidebar main" 1fr
    / 200px 1fr;
  
  /* 更复杂的简写 */
  grid: auto-flow dense 100px / 1fr 2fr;
}

2. 项目属性 (Item Properties)

grid-column-start / grid-column-end / grid-row-start / grid-row-end

基于网格线定位项目

css

.item {
  grid-column-start: 1;      /* 从第1条垂直线开始 */
  grid-column-end: 3;        /* 到第3条垂直线结束 */
  grid-row-start: 2;         /* 从第2条水平线开始 */
  grid-row-end: 4;           /* 到第4条水平线结束 */
  
  /* 使用负值从末尾计数 */
  grid-column-end: -1;       /* 到最后一列 */
  
  /* 使用 span 关键字 */
  grid-column-end: span 2;   /* 跨越2列 */
}

grid-column / grid-row

grid-column-start + grid-column-end 和 grid-row-start + grid-row-end 的简写

css

.item {
  /* 语法: start-line / end-line */
  grid-column: 1 / 3;        /* 从第1线到第3线 */
  grid-column: 1 / span 2;   /* 从第1线开始跨越2列 */
  grid-column: 2 / -1;       /* 从第2线到最后一列 */
  
  grid-row: 1 / 4;           /* 从第1线到第4线 */
  grid-row: span 2;          /* 跨越2行 */
  
  /* 只设置开始线,自动结束 */
  grid-column: 2;            /* 从第2线开始 */
}

grid-area

为项目指定区域名称,或作为 grid-row-start + grid-column-start + grid-row-end + grid-column-end 的简写

css

.item {
  /* 作为区域名称 */
  grid-area: header;
  
  /* 作为定位简写 */
  /* 语法: row-start / column-start / row-end / column-end */
  grid-area: 1 / 1 / 3 / 3;  /* 行开始 / 列开始 / 行结束 / 列结束 */
  grid-area: 2 / 1 / span 2 / span 3;
}

justify-self

沿着行轴对齐单个网格项内的内容

css

.item {
  justify-self: start;      /* 左对齐 */
  justify-self: end;        /* 右对齐 */
  justify-self: center;     /* 居中对齐 */
  justify-self: stretch;    /* 拉伸填充(默认) */
}

align-self

沿着列轴对齐单个网格项内的内容

css

.item {
  align-self: start;        /* 顶部对齐 */
  align-self: end;          /* 底部对齐 */
  align-self: center;       /* 居中对齐 */
  align-self: stretch;      /* 拉伸填充(默认) */
  align-self: baseline;     /* 基线对齐 */
}

place-self

align-self 和 justify-self 的简写

css

.item {
  place-self: center;            /* align-self justify-self */
  place-self: start end;         /* align-self justify-self */
}

3. 函数和关键字

repeat() 函数

css

.container {
  /* 基本重复 */
  grid-template-columns: repeat(4, 100px);
  
  /* 模式重复 */
  grid-template-columns: repeat(2, 100px 200px); /* 100px 200px 100px 200px */
  
  /* 自动填充 */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

minmax() 函数

css

.container {
  grid-template-columns: minmax(100px, 1fr) minmax(200px, 2fr);
  grid-template-rows: minmax(50px, auto) minmax(100px, 1fr);
}

fit-content() 函数

css

.container {
  grid-template-columns: fit-content(300px) 1fr;
  /* 列宽最小为内容宽度,最大为300px */
}

masonry 实验性特性

css

.container {
  grid-template-rows: masonry; /* 砌体布局(瀑布流) */
}

4. 完整示例

示例1:基础网格布局

html

<div class="grid-container">
  <div class="item header">Header</div>
  <div class="item sidebar">Sidebar</div>
  <div class="item main">Main Content</div>
  <div class="item aside">Aside</div>
  <div class="item footer">Footer</div>
</div>

css

.grid-container {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 80px 1fr 100px;
  grid-template-areas: 
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  gap: 15px;
  height: 100vh;
}

.header { grid-area: header; background: #f0f0f0; }
.sidebar { grid-area: sidebar; background: #e0e0e0; }
.main { grid-area: main; background: #d0d0d0; }
.aside { grid-area: aside; background: #e0e0e0; }
.footer { grid-area: footer; background: #f0f0f0; }

示例2:响应式图片网格

css

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

.gallery-item {
  aspect-ratio: 4/3;
  background: #eee;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  overflow: hidden;
}

示例3:复杂网格定位

css

.dashboard {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: 60px 200px 1fr 100px;
  gap: 20px;
  height: 100vh;
}

.stats-card:nth-child(1) { grid-column: 1 / 5; }
.stats-card:nth-child(2) { grid-column: 5 / 9; }
.stats-card:nth-child(3) { grid-column: 9 / 13; }

.chart-large {
  grid-column: 1 / 9;
  grid-row: 2 / 4;
}

.chart-small {
  grid-column: 9 / 13;
  grid-row: 2 / 3;
}

.side-panel {
  grid-column: 9 / 13;
  grid-row: 3 / 4;
}

示例4:网格线命名

css

.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] 1fr 
    [main-end footer-start] 100px 
    [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;
}

5. 浏览器支持和最佳实践

浏览器支持

  • 现代浏览器全面支持
  • IE10/11 支持旧语法(带 -ms- 前缀)

前缀使用

css

.container {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
}

渐进增强

css

/* 浮动布局作为回退 */
.item {
  float: left;
  width: 33.33%;
}

/* Grid 布局增强 */
@supports (display: grid) {
  .container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
  }
  .item {
    float: none;
    width: auto;
  }
}

Grid 布局提供了强大的二维布局能力,通过合理使用这些属性,可以创建出各种复杂的响应式布局。