引言

CSS Grid Layout(网格布局)是CSS最强大的布局系统。与Flexbox专注于一维布局不同,Grid是为二维布局而设计的——同时处理行和_column_。自2017年以来获得了所有现代浏览器的支持,它彻底改变了我们构建Web布局的方式。本指南将从基础概念出发,系统性地掌握Grid布局的每一个层面。

一、Grid基础概念

1.1 网格容器与网格项目

Grid布局涉及两个核心角色:网格容器(设置display: grid的元素)和网格项目(容器的直接子元素)。


.grid-container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 100px 100px;
    gap: 10px;
}
  • 网格容器(Grid Container):应用display: grid的元素
  • 网格项目(Grid Item):容器的直接子元素成为网格项目
  • 网格线(Grid Line):网格结构中的分界线,从1开始编号
  • 网格轨道(Grid Track):相邻网格线之间的空间,即行或列
  • 网格单元格(Grid Cell):网格中的单个格子
  • 网格区域(Grid Area):由网格线围成的矩形区域

1.2 显示网格与隐式网格

Grid包含两类网格:

  • 显式网格(Explicit Grid):通过grid-template-columns和grid-template-rows明确创建的网格
  • 隐式网格(Implicit Grid):当项目超出显式网格时自动创建的轨道

.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* 显式创建3列 */
    grid-auto-rows: minmax(100px, auto); /* 隐式行自动高度 */
}

二、定义网格轨道

2.1 固定与弹性单位

Grid提供了丰富的单位来定义轨道尺寸:

单位说明示例
px固定像素grid-template-columns: 200px 200px
fr弹性分数单位grid-template-columns: 1fr 2fr(2:1比例)
%百分比grid-template-columns: 25% 75%
auto内容自适应grid-template-columns: auto 1fr
minmax()范围限制grid-template-columns: minmax(200px, 1fr)
min-content最小内容宽度grid-template-columns: min-content 1fr
max-content最大内容宽度grid-template-columns: max-content 1fr

2.2 repeat()函数与auto-fill/auto-fit

repeat()简化重复轨道的定义,结合auto-fill和auto-fit可以实现无需媒体查询的响应式网格:


/* 传统写法 */
grid-template-columns: 1fr 1fr 1fr 1fr;

/* 使用repeat() */
grid-template-columns: repeat(4, 1fr);

/* auto-fill: 尽可能创建轨道(即使空着) */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

/* auto-fit: 折叠空轨道,填充可用空间 */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

auto-fill vs auto-fit的关键区别:当项目数量少于可容纳的轨道数时,auto-fill保留空轨道占位,auto-fit则将空轨道折叠为零宽度,让已有项目扩展填满。

2.3 grid-auto-rows 与 grid-auto-columns

控制隐式创建的轨道尺寸:


.grid {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: 200px; /* 仅第一行200px高 */
    grid-auto-rows: minmax(100px, auto); /* 隐式行最小100px,最大自适应 */
}

三、网格线布局

3.1 基于线的定位

每个网格线都可以通过编号引用,正数从左/上开始,负数从右/下开始:


.item {
    grid-column-start: 1;
    grid-column-end: 3;    /* 跨越第1到第3条列线(占2列) */
    grid-row-start: 1;
    grid-row-end: 2;       /* 在第1行 */
}

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

/* 使用span跨越若干轨道 */
.item {
    grid-column: span 2;   /* 跨越2列 */
    grid-row: span 3;      /* 跨越3行 */
}

/* 负数从末尾计数 */
.item {
    grid-column: 1 / -1;   /* 从第一列到最后一列,横跨整个容器 */
}

3.2 网格线命名

通过方括号语法为网格线命名,使定位更可读:


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

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

四、网格区域模板

4.1 grid-template-areas

grid-template-areas提供了最直观的布局方式——通过ASCII模板定义布局:


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

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

使用点号(.)表示空单元格:


grid-template-areas:
    "header  header header"
    "sidebar .      main"
    "footer  footer footer";

4.2 grid-area 简写

grid-area可以同时指定四条线:


/* grid-area: row-start / column-start / row-end / column-end */
.item {
    grid-area: 1 / 2 / 3 / 4;
    /* 等同于:从第1行线到第3行线,从第2列线到第4列线 */
}

五、间距与对齐

5.1 网格间距(Gap)


.grid {
    gap: 20px;                    /* 行列间距相同 */
    row-gap: 20px;                /* 行间距 */
    column-gap: 30px;             /* 列间距 */
    gap: 20px 30px;               /* 行间距 列间距 */
}

5.2 项目对齐(align/justify)

Grid提供了一套完整的对齐系统:


/* 容器级别:所有项目整体对齐 */
.grid {
    justify-content: center;  /* 列方向:start | end | center | stretch | space-around | space-between | space-evenly */
    align-content: center;    /* 行方向:同上 */
}

/* 项目级别:单个项目在自身单元格内对齐 */
.item {
    justify-self: center;     /* 列方向 */
    align-self: center;       /* 行方向 */
}

/* 简写 */
.item {
    place-self: center center; /* align-self justify-self */
}

.grid {
    place-content: center center; /* align-content justify-content */
}

六、高级技巧

6.1 重叠与z-index

Grid天然支持项目重叠,通过z-index控制堆叠顺序:


.grid {
    grid-template-columns: repeat(3, 1fr);
}

.overlay {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    z-index: 2;
}

.background {
    grid-column: 2 / 4;
    grid-row: 1 / 3;
    z-index: 1;
    opacity: 0.5;
}

6.2 子网格(Subgrid)

Subgrid允许嵌套网格继承父网格的轨道定义,解决对齐一致性问题:


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

.card {
    display: grid;
    grid-template-rows: subgrid; /* 继承父网格的行轨道 */
    grid-row: span 3;
}

/* 卡片内的标题、描述、底部会自动与同行其他卡片对齐 */

6.3 使用 container queries 配合 Grid

现代CSS中,将Grid与容器查询结合,可以实现组件级的响应式:


.card-container {
    container-type: inline-size;
    display: grid;
    grid-template-rows: auto 1fr auto;
}

@container (min-width: 600px) {
    .card {
        grid-template-columns: 200px 1fr;
        grid-template-rows: auto;
    }
}

七、实战案例

7.1 Holy Grail布局


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

@media (max-width: 768px) {
    .page {
        grid-template-areas:
            "header"
            "nav"
            "main"
            "aside"
            "footer";
        grid-template-columns: 1fr;
    }
}

7.2 响应式图片画廊


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

.gallery img {
    width: 100%;
    height: 250px;
    object-fit: cover;
    border-radius: 8px;
}

/* 特色图片占据更大的空间 */
.featured {
    grid-column: span 2;
    grid-row: span 2;
}

.featured img {
    height: 100%;
}

7.3 仪表板布局


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

.sidebar {
    grid-column: 1;
    grid-row: 1 / -1; /* 横跨所有行 */
}

.widget {
    /* 每个widget自动放置到可用位置 */
}

.wide-widget {
    grid-column: span 2; /* 宽widget占2列 */
}

八、Grid vs Flexbox选型指南

场景推荐方案
整体页面布局(页头/侧栏/主体/页脚)Grid(二维)
导航栏、按钮组、标签栏Flexbox(一维)
卡片网格/图片画廊Grid + auto-fit
表单元素对齐Flexbox 或 Grid 均可
不规则网格响应式布局Grid + 媒体查询
单项导航/左标签右按钮Flexbox
需要精确对齐多个维度Grid

九、浏览器兼容性与降级策略

Grid在现代浏览器中拥有极佳的支持率(全球约97%+)。对于需要支持旧版本浏览器的项目,可以采用渐进增强策略:


/* 基础布局:使用Flexbox或float */
.layout {
    display: flex;
    flex-wrap: wrap;
}

.layout > * {
    flex: 1 1 300px;
}

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

总结

CSS Grid是现代Web布局的核心工具,掌握它能够让你摆脱对绝对定位和复杂浮动的依赖。关键要点回顾:

  • Grid处理二维布局,Flexbox处理一维布局,两者互补而非替代
  • fr单位 + auto-fit/auto-fill实现了无需媒体查询的响应式网格
  • grid-template-areas让复杂布局一目了然
  • Subgrid解决了嵌套组件的对齐一致性问题
  • @supports渐进增强确保兼容性

从今天开始告别布局hack,拥抱Grid带来的纯粹与优雅。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
网站二维码

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部