前言
在《前端必备CSS布局之弹性(Flex)布局》这篇文章中,我们介绍了当今CSS的半壁江山——弹性布局,现在我们就来在这篇文章中讲完剩下的半壁江山——Grid布局。GO,GO,GO,出发咯。
一、什么是Grid布局?
定义
Grid 布局(网格布局)是 CSS 中最强大的布局系统之一,它将页面划分为二维网格(行和列),能轻松实现复杂的布局结构。相比 Flexbox 的一维布局,Grid 更适合整体页面布局或具有复杂嵌套关系的组件布局。
- 核心概念:
- 网格容器(Grid Container) :应用
display: grid(块级Grid容器)或display: inline-grid(行内级Grid容器)的元素,其所有直接子元素自动成为 “项目”。 - 网格项目(Grid Items) :容器的直接子元素(不包含孙子元素,和弹性布局一样)。
- 网格线(Grid Lines) :划分网格的线条(水平为行线,垂直为列线),编号从 1 开始。
- 网格轨道(Grid Tracks) :行线或列线之间的区域(即 “行” 或 “列”)。
- 网格单元格(Grid Cell) :单个行与列交叉的最小区域(类似表格的单元格)。
- 网格区域(Grid Area) :多个相邻单元格组成的矩形区域。
- 网格容器(Grid Container) :应用
示图
二、Grid布局属性
和 Flex 布局类似,Grid 布局的属性也分为容器属性和项目属性,分别控制容器和项目的规则。接下来我将分别讲述这两者。
(一)开启Grid布局
.container {
display: grid;
}
(二)便捷操作
除了固定死的绝对单位px,Grid布局中还有一些属性可以便捷地进行布局设置。
相对尺寸单位(fr)
除了可以设置绝对尺寸单位px,我们还可以使用fr这个相对单位。
-
fr:表示 “剩余空间的比例”。例如1fr 2fr表示两列按 1:2 分配剩余空间(先扣除固定尺寸,再分剩余,我感觉很像是弹性布局里面的flex-grow)。 -
用法示例:这会创建三列,中间列的宽度是两侧列的两倍。
.container { display: grid; grid-template-columns: 1fr 2fr 1fr; height: 200px; } -
完整示例:
简化重复值(repeat()函数)
对于重复的值,可以使用repeat()函数来简化代码。例如 grid-template-columns: repeat(3, 1fr) 等价于 1fr 1fr 1fr;repeat(2, 100px 200px) 等价于 100px 200px 100px 200px。
-
用法示例:
.container { display: grid; grid-template-columns: repeat(3, 1fr); /* 等同于 grid-template-columns: 1fr 1fr 1fr; */ /* 也可以重复多个值 */ grid-template-columns: repeat(2, 100px 200px); /* 等同于 grid-template-columns: 100px 200px 100px 200px; */ } -
完整示例:
尺寸范围(minmax()函数)
minmax()函数定义了一个大小范围,不小于最小值,不大于最大值。
-
用法示例:下面的代码确保了第一列和第三列至少有
100px宽,但可以根据可用空间扩展;第一行至少有50px高,但可以根据内容自动增高。.container { display: grid; grid-template-columns: minmax(100px, 1fr) 2fr minmax(100px, 1fr); grid-template-rows: minmax(50px, auto) 100px; } -
完整示例:
自动填充列(auto-fill/auto-fit)
auto-fill/auto-fit是 Grid 布局中用于实现响应式列布局的关键字,配合 repeat() 和 minmax() 使用,能根据容器宽度自动计算列数(无需媒体查询)。核心区别在于处理剩余空间时:auto-fill 保留空列,auto-fit 折叠空列并拉伸现有列。
-
用法示例:
.container { display: grid; /* 尽可能创建更多的列,每列至少200px宽 */ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* 类似auto-fill,但会折叠空列 */ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } -
完整示例:
(三)容器属性(定义网格结构)
容器属性决定网格的行列结构、间距、对齐方式等,是布局的核心配置。
1. 定义网格结构
行列(grid-template-rows/grid-template-columns)
这两个属性是Grid布局的核心,用于定义行轨道和列轨道的尺寸(其实就是每行每列各自的宽度)。
- 语法:
grid-template-columns: <轨道尺寸>...(列);grid-template-rows: <轨道尺寸>...(行)。 - 用法示例:
.container { display: grid; /* 分别定义了三列,其列尺寸为100px、200px、100px */ grid-template-columns: 100px 200px 100px; /* 分别定义了两行,其行尺寸为50px、100px */ grid-template-rows: 50px 100px; } - 完整示例:创建了一个3列2行的网格,其中列宽分别为100px、200px和100px,行高分别为50px和100px。
网格区域命名:grid-template-areas
通过命名区域简化项目定位(适合复杂布局,如页面布局),需配合项目的 grid-area 属性使用。
-
规则:
- 用字符串表示行,同一行的区域用空格分隔
- 同名区域必须形成矩形(不能是 “L” 形)
.表示空单元格
-
用法示例:
.container { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: auto auto auto; grid-template-areas: "header header header" "sidebar content content" "footer footer footer"; } -
完整示例:
简写(grid-template)
grid-template是grid-template-rows、grid-template-columns和grid-template-areas的简写属性。
-
用法示例:
.container { display: grid; grid-template: "header header header" auto "sidebar content content" 1fr "footer footer footer" auto / 1fr 2fr 1fr; } -
完整示例:
2. 网格间距(gap)
gap, row-gap, column-gap这些属性用于设置网格线的大小(即行与行、列与列之间的间距)。
-
用法示例:
.container { display: grid; grid-template-columns: repeat(3, 1fr); /* 设置所有间距 */ gap: 20px; /* 或者分别设置 */ row-gap: 20px; column-gap: 10px; } -
完整示例:
3. 对齐
网格对齐(整体网格在容器中的位置)
当网格总尺寸 <容器尺寸时,控制网格整体的对齐方式(区分 “项目在单元格内” 和 “网格在容器内”)。
-
属性:
- 水平方向(行轴) :
justify-content - 垂直方向(列轴) :
align-content
- 水平方向(行轴) :
-
简写:
place-content: 垂直 水平(单值时两者相同).container { display: grid; /* 同时设置垂直和水平对齐 */ place-content: center; /* 等同于 align-content: center; justify-content: center; */ place-content: start end; /* 等同于 align-content: start; justify-content: end; */ } -
取值说明(共通):
start:靠起始端对齐(左 / 上)end:靠结束端对齐(右 / 下)center:居中space-between:两端对齐,中间间距平均space-around:项目两侧间距相等(边缘间距是中间的一半)space-evenly:所有间距(包括边缘)完全相等
-
完整示例:
项目对齐(项目在单元格内的位置)
控制所有项目在各自单元格内的对齐方式(单元格是项目的 “容器”)。
-
属性:
- 水平方向:
justify-items - 垂直方向:
align-items
- 水平方向:
-
简写:
place-items: 垂直 水平.container { display: grid; /* 同时设置垂直和水平项目对齐 */ place-items: center; /* 等同于 align-items: center; justify-items: center; */ place-items: start end; /* 等同于 align-items: start; justify-items: end; */ } -
取值说明(共通):
start:单元格起始端(左 / 上)end:单元格结束端(右 / 下)center:单元格居中stretch:默认值,拉伸填满单元格
-
完整示例:
4. 隐式轨道(grid-auto-rows / grid-auto-columns)
当项目数量超过定义的行列数时,Grid 会自动创建 “隐式轨道”(默认尺寸为 auto)。grid-auto-rows 以及 grid-auto-columns这两个属性用于定义隐式轨道的尺寸。
-
注意:隐式不代表看不到,作为一个完整的布局系统,Grid 不会让多余的项目 “消失” 或 “溢出容器”,而是会自动创建新的轨道来放置剩余项目。这些 “额外创建的轨道” 就是隐式轨道。
-
用法示例:定义 2 行,但有 5 个项目(会生成 3 行隐式轨道):
.container { grid-template-rows: 50px 50px; /* 显式定义 2 行 */ grid-auto-rows: 80px; /* 隐式行轨道高度为 80px */ } -
完整示例:
(四)项目属性(控制项目位置和大小)
项目属性用于调整单个项目的布局(覆盖容器的默认设置)。
1. 项目定位(grid-column / grid-row)
通过「网格线编号」或「跨轨道数量」控制项目占据的行列范围(核心属性)。
- 语法:
grid-column: 起始列线 / 结束列线(简写,等价于grid-column-start/grid-column-end)grid-row: 起始行线 / 结束行线(等价于grid-row-start/grid-row-end)
- 关键用法:
- 网格线编号:从 1 开始(例如
grid-column: 1 / 3表示从第 1 列线到第 3 列线,跨 2 列)。 span关键字:表示 “跨多少轨道”(例如grid-column: 1 / span 2等价于1 / 3)。
- 网格线编号:从 1 开始(例如
- 示例代码:
2. 关联区域(grid-area)
配合容器的 grid-template-areas 使用,指定项目属于哪个命名区域。
-
用法示例:将项目对应到
header区域。.header { grid-area: header; /* 对应容器中定义的 header 区域 */ }
也可直接用网格线简写:grid-area: 起始行线 / 起始列线 / 结束行线 / 结束列线(等价于 grid-row + grid-column)。
- 完整示例:
3. 单个项目对齐(justify-self / align-self)
覆盖容器的 justify-items / align-items,单独控制某个项目在单元格内的对齐方式。
-
取值同
justify-items/align-items(start/end/center/stretch)。 -
简写:
place-self: 垂直 水平 -
完整示例:
三、Grid布局实战
1. 经典网页布局
2. 照片墙布局
3. 仪表盘布局
四、兼容性问题
-
支持:Grid布局现在已经得到了所有主流浏览器的良好支持:
- Chrome 57+
- Firefox 52+
- Safari 10.1+
- Edge 16+
- Opera 44+
-
不支持:IE 全版本
支持旧版
对于需要支持旧版浏览器的项目,可以考虑使用以下策略:
1. 检测兼容性
-
CSS原生检测(推荐):使用
@supports规则检测浏览器是否支持Grid/* 支持Grid的浏览器用Grid样式 */ @supports (display: grid) { .container { display: grid; /* 其他Grid属性 */ } } /* 不支持的用后备样式 */ @supports not (display: grid) { .container { display: flex; /* 其他降级样式 */ } } -
JS 辅助检测(复杂场景用):
const supportsGrid = window.CSS?.supports('display', 'grid'); // 根据结果动态添加类名或样式
2. 降级策略
-
主要方案:用 Flexbox 替代(支持更早,适配一维布局)
- 多列布局:
flex-wrap: wrap+ 百分比宽度 - 模拟 gap:父容器负 margin + 子元素 padding
- 多列布局:
-
工具辅助:用 Autoprefixer 自动添加浏览器前缀(如 IE11 的
-ms-前缀)
项目运用
- 现代项目(无 IE 需求):直接用 Grid,无需过度降级
- 需兼容旧浏览器:先实现 Flexbox 基础布局,再用 Grid 增强现代浏览器体验
结语
CSS Grid布局是一个强大而灵活的布局系统,它彻底改变了我们设计网页布局的方式。虽然学习曲线可能比Flexbox稍陡,但掌握Grid布局绝对值得投入时间,它将成为你前端开发工具箱中的强大武器。最佳实践是将Grid用于整体页面布局,而Flexbox用于组件内部的一维布局,两者结合使用可以创建出既灵活又强大的现代网页布局。
如果这篇文章有帮助到你,不胜荣幸;如果文章有错误或者缺漏,请在评论区指出,大家一起进步,谢谢🙏。