网格布局(display:grid)属性详解


CSS Grid 布局(display: grid)是一种强大的二维布局系统,能够通过行和列的网格结构精确控制页面元素的排列。它能够将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。

一、基本概念

1.容器与项目

通过设置 display: griddisplay: inline-grid 的区域,称为”容器”(container)。其容器内部采用网格定位的子元素自动成为项目(Grid Item)。

<div>
    <div><p>1</p></div>
    <div><p>2</p></div>
    <div><p>3</p></div>
</div>

上面代码中,最外层的 <div> 元素就是容器,内层的三个 <div> 元素就是项目。

注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的 <p> 元素就不是项目。Grid 布局只对项目生效。

2.行与列

容器里面的水平区域称为行(row),垂直区域称为列(column)。行和列之间的交叉区域,称为单元格(cell)。

上图中,水平的深色区域就是”行”,垂直的深色区域就是”列”。

正常情况下,n 行和 m 列会产生 n x m 个单元格。比如,3 行 3 列会产生 9 个单元格。

3.网格线与轨道

网格线:划分网格的线,称为”网格线”(grid line)。水平网格线划分出行,垂直网格线划分出列。划分行和列的虚拟线,通过编号或自定义名称引用(如 c1, r2)。

轨道:相邻网格线之间的区域,即行或列的宽度/高度。

二、容器属性

Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性

1.grid-template-columns 与 grid-template-rows

grid-template-columnsgrid-template-rows分别定义显式网格的列宽和行高,支持多种单位(如 pxfr%)和函数(如 repeat()minmax()):

.container {
    grid-template-columns: repeat(3, 1fr); /* 三列等宽 */
    grid-template-rows: 100px auto minmax(200px, 1fr); /* 行高灵活 */
}

2.grid-template-areas

网格布局允许指定”区域”(area),一个区域由单个或多个单元格组成。

.container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas:
        "a b c"
        "d e f"
        "g h i";
}

上面代码先划分出 9 个单元格,然后将其定名为ai的九个区域,分别对应这九个单元格。

多个单元格合并成一个区域的写法如下。

grid-template-areas:
    "a a a"
    "b b b"
    "c c c";

上面代码将 9 个单元格分成abc三个区域。

下面是一个布局实例。

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

上面代码中,顶部是页眉区域header,底部是页脚区域footer,中间部分则为mainsidebar

如果某些区域不需要利用,则使用”点”(.)表示。

grid-template-areas:
    "a . c"
    "d . f"
    "g . i";

上面代码中,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域。

注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

比如,区域名为header,则起始位置的水平网格线和垂直网格线叫做header-start,终止位置的水平网格线和垂直网格线叫做header-end

2.1 repeat()

有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。上面的代码用repeat()改写如下。

.container {
    display: grid;
    grid-template-columns: repeat(3, 33.33%);
    grid-template-rows: repeat(3, 33.33%);
}

repeat()接受两个参数,第一个参数是重复的次数(上例是 3),第二个参数是所要重复的值。

repeat()重复某种模式也是可以的。

grid-template-columns: repeat(2, 100px 20px 80px);

上面代码定义了 6 列,第一列和第四列的宽度为100px,第二列和第五列为20px,第三列和第六列为80px

2.2 fr

网格布局提供了fr(fraction 的缩写,意为”片段”)来表示比例关系。如果两列的宽度分别为1fr2fr,就表示后者是前者的两倍。

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

2.3 minmax()

minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。

grid-template-columns: 1fr 1fr minmax(100px, 1fr);

上面代码中,minmax(100px, 1fr)表示列宽不小于100px,不大于1fr

2.4 auto

auto表示由浏览器自己决定长度。

grid-template-columns: 100px auto 100px;

上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格里的内容设置了min-width,且这个值min-width大于该列单元格的最大宽度。

2.5 auto-fill

有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill表示自动填充。

.container {
    display: grid;
    grid-template-columns: repeat(auto-fill, 100px);
}

上面代码表示每列宽度100px,然后自动填充,直到容器不能放置更多的列。

3.grid-auto-columns 与 grid-auto-rows

有时候,一些项目的指定位置,在现有网格的外部。比如网格只有 3 列,但是某一个项目指定在第 5 行。这时,浏览器会自动生成多余的网格,以便放置项目。

grid-auto-columns属性和grid-auto-rows属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与grid-template-columnsgrid-template-rows完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。

下面案例中,划分好的网格是 3 行 x 3 列,但是,8 号项目指定在第 4 行,9 号项目指定在第 5 行。

#container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-auto-rows: 50px;
}

.item {
    font-size: 2em;
    text-align: center;
    border: 1px solid #e5e4e9;
}

.item-1 {
    background-color: #ef342a;
}

.item-2 {
    background-color: #f68f26;
}

.item-3 {
    background-color: #4ba946;
}

.item-4 {
    background-color: #0376c2;
}

.item-5 {
    background-color: #c077af;
}

.item-6 {
    background-color: #f8d29d;
}

.item-7 {
    background-color: #b5a87f;
}

.item-8 {
    background-color: #d0e4a9;
    grid-row-start: 4;
    grid-column-start: 2;
}

.item-9 {
    background-color: #4dc7ec;
    grid-row-start: 5;
    grid-column-start: 3;
}

4.grid-gap

gap:设置行间距和列间距(替代旧版 grid-gap),简写形式为 gap: 行间距 列间距

.container {
    gap: 10px 20px;
} /* 行距10px,列距20px */

5.grid-row-gap、grid-column-gap和grid-gap

grid-row-gap属性设置行与行的间隔(行间距),grid-column-gap属性设置列与列的间隔(列间距)。

grid-gap属性是grid-column-gapgrid-row-gap的合并简写形式

grid-gap: <grid-row-gap> <grid-column-gap>;

如果grid-gap省略了第二个值,浏览器认为第二个值等于第一个值。

6. justify-items 与 justify-content

  • 项目对齐justify-items(水平)、align-items(垂直),默认拉伸填充(stretch)。
  • 整体对齐justify-content(水平整体位置)、align-content(垂直整体位置),适用于网格总尺寸小于容器时。

该方法的使用和 Flex 弹性布局类似,此处不在过多赘述。

三、项目属性

1 grid-column-start、grid-column-end、grid-row-start、grid-row-end

项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线。

  • grid-column-start属性:左边框所在的垂直网格线
  • grid-column-end属性:右边框所在的垂直网格线
  • grid-row-start属性:上边框所在的水平网格线
  • grid-row-end属性:下边框所在的水平网格线
.item-1 {
    grid-column-start: 2;
    grid-column-end: 4;
}

上述代码指:1 号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。

2.grid-column 与 grid-row

grid-column属性是grid-column-startgrid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

.item {
    grid-column: 1 / 3; /* 跨越第1至第3列 */
    grid-row: 2; /* 仅在第2行 */
}

.item-1 {
    grid-column: 1 / 3;
    grid-row: 1 / 2;
}
/* 等同于 */
.item-1 {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 2;
}

3.grid-area

grid-area直接指定项目所属的命名区域(需配合 grid-template-areas)。

#container {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas:
        "a b c"
        "d e f"
        "g h i";
}

.item {
    font-size: 4em;
    text-align: center;
    border: 1px solid #e5e4e9;
}

.item-1 {
    background-color: #ef342a;
    grid-area: e;
}

.item-2 {
    background-color: #f68f26;
}

.item-3 {
    background-color: #4ba946;
}

.item-4 {
    background-color: #0376c2;
}

.item-5 {
    background-color: #c077af;
}

.item-6 {
    background-color: #f8d29d;
}

.item-7 {
    background-color: #b5a87f;
}

.item-8 {
    background-color: #d0e4a9;
}

.item-9 {
    background-color: #4dc7ec;
}

1 号项目位于e区域,效果如下图。

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

.item {
    grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}

4.justify-self 与 align-self

justify-self 属性设置单元格内容的水平位置(左中右),跟 justify-items 属性的用法完全一致,但只作用于单个项目

align-self 属性设置单元格内容的垂直位置(上中下),跟 align-items 属性的用法完全一致,也是只作用于单个项目

.item {
    justify-self: start | end | center | stretch;
    align-self: start | end | center | stretch;
}

这两个属性都可以取下面四个值。

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

四、高级技巧与应用场景

1. 响应式布局

auto-fillminmax() 结合:动态调整列数以适应容器宽度:

.container {
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

2. 复杂布局示例

1.等分三栏布局

.container {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr; /* 中间栏宽为两侧两倍 */
    gap: 20px;
}

2.卡片网格

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

3.后台管理布局

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

.header {
    grid-area: header;
    background: red;
}

.aside {
    grid-area: aside;
    background: blue;
}

.main {
    grid-area: main;
    background: #f5f5f5;
}

.footer {
    grid-area: footer;
    background: yellow;
}

五、与 Flex 布局对比

特性 Grid 布局 Flex 布局
维度 二维(行+列) 一维(单行/列)
适用场景 复杂网格结构(如仪表盘) 线性排列(如导航栏)
控制粒度 单元格级别 轴线级别
对齐方式 支持行列双向对齐 仅单轴对齐

六、兼容性与总结

  • 兼容性:现代浏览器(Chrome、Firefox、Safari、Edge)均支持,IE 部分支持需前缀。
  • 总结:Grid 布局通过行、列和区域的灵活定义,解决了传统布局难以实现的复杂结构问题,尤其适合响应式设计和多维内容排列。结合 Flex 布局,可覆盖绝大多数页面排版需求。

参考:


文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
  目录