CSS | 是时候学习 Grid 布局了

2024-02-21
330512 分钟
...

在前端开发中,创建灵活且响应式的布局是非常重要的。为了实现这一目标,Grid 网格布局成为了一种强大的工具。它提供了一种直观且灵活的方式来构建网页布局,本文将从Grid的基本概念入手,介绍Grid网格布局中的常用属性和功能。那么下面我们一起来探索这个强大且灵活的布局方式吧!

  • Flex布局是一维的排版方式,也就是说一次只能控制一个方向(水平方向或者垂直方向),如果需要控制另一个方向需要再添加一层flexbox容器。
  • Grid布局是二维的排版方式,一次能控制两个方向,通过将容器分成行和列,便可定义容器内元素的位置。

行与列的概念(row & column)

  • 水平区域——行
  • 垂直区域——列

单元格(cell)

  • 行和列交叉的区域就为一个单元格
  • 正常情况下,n行和m列产生m*n个单元格->5行5列=5*5=25个单元格

网格线(grid line)

  • 划分网格的线,称为"网格线"(grid line)。

  • 水平网格线划分出行,垂直网格线划分出列。

  • 正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线。

    比如下图5行5列的情况下,有6根水平网格线和6根垂直网格线。

首先需要准备一个容器元素

<div class="container"></div>

然后设定容器的display:grid即可

.container {
    display: grid;
    width: 500px;
    height: 500px;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
}

❕注:Grid布局分为display:griddisplay: inline-gridgrid下容器元素都是块级元素,而inline-grid则是行内元素。

  • grid-template-rows属性:定义每一行的行高
  • grid-template-columns属性:定义每一列的列宽

比如,下面将grid-template-rowsgrid-template-columns都设定为5个100px,中间用空格隔开,grid-template-rows代表垂直方向分割出5个高度为100px的空间,grid-template-columns代表水平方向分割出5个高度为100px的空间。

.container {
  display: grid;
  grid-template-rows: 100px 100px 100px 100px 100px;
  grid-template-columns: 100px 100px 100px 100px 100px;
  width: 500px;
  height: 500px;
  border: 1px solid rgb(0, 0, 0);
  background-color: #eee;
}

repeat()函数

如果觉得定义行高(grid-template-rows)以及列宽(grid-template-columns)的时候重复书写某个值很麻烦,那么就可以考虑使用repeat()函数。

语法:

repeat(<length>, [<value> | <mode>])

  • 参数1length:需要重复的次数
  • 参数2[<value> | <mode>]:需要重复的值,可以是百分比、具体的值或者是某种模式

比如上面的定义行高与列宽中的代码就可以改写为下面这样

.container {
  display: grid;
  grid-template-rows: repeat(5, 100px);
  grid-template-columns: repeat(5, 100px);
  width: 500px;
  height: 500px;
  border: 1px solid rgb(0, 0, 0);
  background-color: #eee;
}
  • repeat()可以和正常的设定值混用
grid-template-rows: 100px repeat(2, 100px 100px);

fr 关键字

如果想按照比例分配行高(grid-template-rows)以及列宽(grid-template-columns)的值,那么就可以使用fr关键字(Fraction,意为"片段")。

  • fr表示比例,1fr表示占1份。
  • 如果将上面的grid-template-rows: repeat(5, 100px)改为grid-template-rows: repeat(5, 1fr),即表示即各占5分之1的空间。
  • fr关键字同样可以和正常的设定值混用
grid-template-rows: 1fr repeat(2, 1fr 1fr);

auto-fill关键字

有时,单元格的大小是固定的,但是容器的大小不确定。

如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。

grid-template-columns: repeat(auto-fill, 100px);

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

HTML:

<div class="container">
  <div class="number cell1">1</div>
  <div class="number cell2">2</div>
  <div class="number cell3">3</div>
  <div class="number cell4">4</div>
  <div class="number cell5">5</div>
  <div class="number cell6">6</div>
  <div class="number cell7">7</div>
  <div class="number cell8">8</div>
  <div class="number cell9">9</div>
</div>

CSS:

.container {
  display: grid;
  width: 500px;
  height: 500px;
  background-color: #eee;
  border: 1px solid rgb(0, 0, 0);
  grid-template-rows: repeat(5, 100px);
  grid-template-columns: repeat(auto-fill, 200px);
}

.cell1 {
  background-color: blue;
}

.cell2 {
  background-color: yellow;
}

.cell3 {
  background-color: orange;
}

.cell4 {
  background-color: black;
  color: white;
}

.cell5 {
  background-color: #c077af;
}

.cell6 {
  background-color: #f8d29d;
}

.cell7 {
  background-color: #b4a87f;
}

.cell8 {
  background-color: #d0e4a8;
}

.cell9 {
  background-color: #4dc7ec;
}

效果图:

auto关键字

auto关键字可以让浏览器自己决定长度。

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

上面的意思是,第二列的宽度,等于该列单元格的最大宽度。

HTML:

<div class="container">
    <div class="number cell1">1</div>
    <div class="number cell2">2</div>
    <div class="number cell3">3</div>
    <div class="number cell4">4</div>
</div>

CSS:

.container {
    display: grid;
    width: 500px;
    height: 500px;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: repeat(5, 100px);
    grid-template-columns: 100px auto 100px;
}

效果图:

❕注:除非单元格内容设置了min-width,且这个值大于最大宽度。

下面给容器添加两个元素,设置对应的背景色

HTML:

<div class="container">
    <div class="number cell1">1</div>
    <div class="number cell2">2</div>
</div>

CSS:

.container {
    width: 500px;
    height: 500px;
    display: grid;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: 100px 100px 100px 100px 100px;
    grid-template-columns: 100px 100px 100px 100px 100px;
}

.number {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: content-box;
    border: 1px solid rgb(117, 117, 117);
    border-radius: 5px;
    box-shadow: 0px 5px 3px #000;
    font-size: 35px;
    font-weight: 800;
}

.cell1 {
    background-color: blue;
}

.cell2 {
    background-color: yellow;
}

效果如图所示:

这个是默认没有定义元素位置的情况,如果想要指定元素位置需要用到grid-rowgrid-column属性。

grid-rowgrid-column

grid-rowgrid-column本身是复合属性。

  • grid-row指定垂直方向上的范围

  • grid-column指定水平方向上的范围

  • grid-row属性的组成部分:

    • grid-row-start:上边框所在的水平网格线
    • grid-row-end:下边框所在的水平网格线
  • grid-column属性的组成部分:

    • grid-column-start:左边框所在的垂直网格线
    • grid-column-end:右边框所在的垂直网格线

如果想使用grid-row,首先指定grid-row-start,然后再指定grid-row-end即可,语法如下:

.cell-1 {
  grid-row: <start-line> / <end-line>
}

gird-column也是如此,也是先指定grid-column-start,然后再指定grid-column-end,语法如下:

.cell-1 {
 grid-column: <start-line> / <end-line>;
}

有了这些前置知识后,现在就可以指定元素的位置了,打个比方,如果想占据让蓝色占据以及黄色占据下图所示的区域

首先来看蓝色的色块:

  • 水平方向上的范围是从1到3,对应的grid-column的值为1 / 3
  • 竖直方向上的范围是1到4,对应的grid-row的值为1 / 4

然后看看黄色的色块:

  • 水平方向上的范围是从3到6,对应的grid-column的值为3 / 6
  • 竖直方向上的范围是4到6,对应的grid-row的值为4 / 6

写出对应的CSS,看看效果:

.cell1 {
    background-color: blue;
    grid-column: 1 / 3;
    grid-row: 1 / 4;
}

.cell2 {
    background-color: yellow;
    grid-column: 3 / 6;
    grid-row: 4 / 6;
}

grid-area(复合属性)

除了可以用grid-columngrid-row指定元素的位置,还可以使用grid-area属性。

  • 该属性为grid-columngrid-row的复合属性

我们直接上代码:

.cell2 {
    background-color: yellow;
    
    grid-row: 4 / 6; */
    grid-area: 4 / 3 / 6 / 6;
}

效果和原本的是一样的,grid-area的设置顺序是:

  1. grid-row的第一个值
  2. grid-column的第一个值
  3. grid-row的第二个值
  4. grid-column的第二个值

可以理解为"坐标",即左上角、右下角坐标。

不过个人不太喜欢用,因为没有grid-rowgrid-column看上去直观。

span关键字

grid-rowgrid-column的设定值是由第几至第几,比如第1至第5:1 / 5

实际在开发过程中是不会有之前图片上那样的标尺的,一遍一眼就可以看出对应的编号的。

因此Grid布局提供了span关键字,span是延伸的意思,所以可以理解为:

  • 第几开始延伸多少格

所以我们可以将蓝色块的代码修改为下面这样:

.cell1 {
    background-color: blue;
    grid-column: 1 / span 3;
    grid-row: 1 / span 2;
}
  • 这里的grid-column意为:从1向后延伸3格
  • 这里的grid-row意为:从1向后延伸2格

效果如下图:

给网格线(grid line)起别名

实际上我们可以给**网格线(grid line)**起别名,代码如下:

.container {
    display: grid;
    grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6];
    grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6];
    width: 500px;
    height: 500px;
    border: 1px solid rgb(0, 0, 0);
    background-color: #eee;
}

对应的代码中也可以使用别名了

.cell1 {
    background-color: blue;
    grid-column: X1 / X6;
    grid-row: Y2 / Y4;
}

给单元格起别名(grid-template-areas

  • 使用grid-template-areas就可以给单元格起别名

首先我们继续给容器增加两个元素

HTML:

<div class="container">
    <div class="number cell1">1</div>
    <div class="number cell2">2</div>
    <div class="number cell3">3</div>
    <div class="number cell4">4</div>
</div>

CSS:

.cell1 {
    background-color: blue;
}

.cell2 {
    background-color: yellow;
}

.cell3 {
    background-color: orange;
}

.cell4 {
    background-color: black;
    color: white;
}

效果图:

现在通过grid-template-areas给容器的各个单元格命名,构建出一个经典的网页布局吧!

.container {
    width: 500px;
    height: 500px;
    display: grid;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6];
    grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6];
    grid-template-areas: 
    "h h h h h"
    "n m m m m"
    "n m m m m"
    "n m m m m"
    
    ". f f f ."
    ;
}

现在对容器中的元素使用grid-area属性,并指定对应grid-template-areas中为方格起的别名即可实现自动填充无需再传入坐标了!

.cell1 {
    background-color: blue;
    grid-area: h;
}

.cell2 {
    background-color: yellow;
    grid-area: n;
}

.cell3 {
    background-color: orange;
    grid-area: m;
}

.cell4 {
    background-color: black;
    color: white;
    grid-area: f;
}

❕注意:repeat()不适用于grid-template-areas中。

行间距与列间距(grid-row/column-gap

如果觉得所有元素紧贴在一起不太好,Grid布局还提供了grid-row-gapgrid-column-gap来增加元素间的行间距与列间距

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

下面我们将刚才写的经典布局的案例的CSS加上这两个属性

.container {
    display: grid;
    width: 500px;
    height: 500px;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6];
    grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6];
    grid-template-areas: 
    "h h h h h"
    "n m m m m"
    "n m m m m"
    "n m m m m"
    
    ". f f f ."
    ;
    row-gap: 10px;
    column-gap: 10px;
}

可以看到内部增加了列间距与行间距后将容器撑大了,所以容器的宽高也需要修改下:

.container {
    display: grid;
    
    height: 500px; */
    width: 540px;
    height: 540px;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px [Y6];
    grid-template-columns: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px [X6];
    grid-template-areas: 
    "h h h h h"
    "n m m m m"
    "n m m m m"
    "n m m m m"
    
    ". f f f ."
    ;
    row-gap: 10px;
    column-gap: 10px;
}

现在看上去就正常了!

grid-auto-flow 关键字

  • Grid布局提供了grid-auto-flow用于控制容器内元素的排列方向(类似Flex布局中的flex-direction+flex-warp:warp的效果)

  • 默认值为row,默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。

  • 设置为column时,表示"先列后行",即先填满第一列,再开始放入第二列,具体参考下图数字的排列顺序。

justify-itemsalign-items

  • justify-items属性设置单元格内容的水平位置(左中右)。
  • align-items属性设置单元格内容的垂直位置(上中下)。

可选值:

  • start:对齐单元格的起始边缘。

  • end:对齐单元格的结束边缘。

  • center:单元格内部居中。

  • stretch:拉伸,占满单元格的整个宽度(默认值)。

比如现在想让容器中元素的编号向左上角对齐可以这么写:

CSS:

.number {
    
    align-items: center;
    justify-content: center; */

    display: grid;
    justify-items: start;
    align-items: start;

    box-sizing: content-box;
    border: 1px solid rgb(117, 117, 117);
    border-radius: 5px;
    box-shadow: 0px 5px 3px #000;
    font-size: 35px;
    font-weight: 800;
}

效果:

place-items(复合属性)

  • 该属性为 justify-itemsalign-items的复合属性

  • 语法

    place-items: <align-items> <justify-items>;
    

比如刚才的代码就可以简写为:place-items: start start;

justify-selfalign-self

  • justify-self属性设置单元格内容的水平位置(左中右),与justify-items用法完全一致,但只作用于单个元素。
  • align-self属性设置单元格内容的垂直位置(上中下),与align-items用法完全一致,但只作用于单个元素。

比如只想要第二个元素向左下角对其,就可以这么写:

CSS:

.cell1 {
    background-color: yellow;
    align-self: start;
    justify-self: start;
}

效果:

place-self(复合属性)

  • 该属性为align-self属性和justify-self属性的复合属性。

  • 语法:

    place-self: <align-self> <justify-self>;
    

所以刚才的代码可以简写为这样:place-self: end end;

justify-contentalign-content

  • justify-content属性是整个内容区域在容器里面的水平位置(左中右)。
  • align-content属性是整个内容区域的垂直位置(上中下)。

取值:

注:下面的图都以justify-content属性为例

CSS:

.container {
    display: grid;
    width: 600px;
    height: 600px;
    background-color: #eee;
    border: 1px solid rgb(0, 0, 0);
    grid-template-rows: repeat(5, 100px);
    grid-template-columns: repeat(5, 100px);
    grid-auto-flow: row;
}
  • start - 对齐容器的起始边框。 默认值

  • end - 对齐容器的结束边框。

  • center - 容器内部居中。

  • stretch - 项目大小没有指定时,拉伸占据整个网格容器。

    移除grid-template-rows以及grid-template-columns

  • space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。

  • space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。

  • space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

place-content(复合属性)

  • 该属性是align-contentjustify-content的复合属性

  • 语法:

    place-content: <align-content> <justify-content>
    

注意:如果省略第二个值,浏览器就会假定第二个值等于第一个值。

GRID GARDEN-链接

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
css2026-06-17
外阴影和内阴影介绍
在前端页面设计中,阴影是非常常见的视觉效果。它可以让元素看起来更有层次感,也可以用来表达悬浮、按压、凹陷、卡片、按钮等状态。 CSS 中最常用的阴影属性是 。它既可以实现外阴影,也可以实现内阴影。 一、什么是外阴影 外阴影指的是元素外部的阴影效果。 它会出现在元素边框之外,让元素看起来像是从页面中“浮起来”了一样。常见的卡片、弹窗、按钮悬浮效果,基本都会用到外阴影。 例如: 这个阴影表示:元素下方有一层柔和的黑色阴影,让卡片看起来更有立...
学习
css2026-05-15
border-image-slice详细介绍
是 CSS 系列属性里最关键、也最容易让人懵的一个属性。 它的作用可以简单理解为: 把一张图片切成九宫格,然后决定哪几块用来绘制元素的边框。 它通常和这些属性一起使用: 或者简写成: 其中 决定“怎么切图”。 一、 是什么? 普通的 只能画纯色边框: 但有时候我们想用图片作为边框,比如: 游戏按钮边框 像素风 UI 复古窗口 聊天气泡 卡牌边框 花纹装饰框 九宫格按钮背景 这时候就可以用 。 例如一张按钮图片长这样: 我们希望按钮变宽时...
学习
css2026-03-05
如何在最小副作用下创建 BFC
在 CSS 布局的江湖中, BFC (Block Formatting Context,块级格式化上下文) 是一个老生常谈却又至关重要的概念。无论是解决 高度塌陷 、 清除浮动 ,还是防止 垂直外边距重叠 ,BFC 都是我们的得力助手。 但是,创建 BFC 的方法有很多: 、 、 、 …… 哪种方法对现有布局的“破坏”最小? ❌ 过去的老方法 在过去,为了触发 BFC,我们不得不使用一些带有副作用的“黑客”技巧: : 元素会脱离文档流,...
学习
css2026-03-03
CSS过渡性能解析:transition: all
CSS过渡性能深度解析:为什么 可能是你页面的隐形杀手 一、引言:一个被忽视的性能陷阱 你是否曾在项目中这样写: 看似简洁优雅,却可能在低端设备上引发卡顿、掉帧。 真相 : 是前端性能优化中高频出现的“隐形陷阱”。本文将彻底揭开它的面纱。 二、核心概念: 到底在控制什么? 指定 哪些CSS属性变化时触发动画过渡 。它是过渡效果的“守门员”: | 值 | 含义 | 生成的CSS | | | | | | | 所有 可过渡属性变化时均触发动画...
学习
css2026-01-26
在CSS中,四种高度视口单位的区别
在CSS中,视口单位是构建响应式网页设计的重要工具,特别是针对移动端开发。除了传统的 ,CSS新引入了 、 和 等更精确的单位,解决传统单位在移动端的局限性。 四种高度视口单位的区别 | 单位 | 全称 | 含义 | 特点 | | | | | | | vh | Viewport Height | 传统视口高度单位,1vh = 视口高度的1% | 在移动端有问题:不考虑浏览器UI变化,经常导致内容被遮挡或出现意外滚动 | | svh |...
学习
css2025-11-04
keyframes 关键帧机制
一、什么是 @keyframes? 用于定义动画在不同时间点(关键帧)的样式变化;配合 属性应用到元素上。 定义动画 :使用 声明关键帧序列; 应用动画 :在选择器中通过 / 相关长属性控制表现。 二、基本语法 等价写法( / ): 三、与 属性配合使用 /相关长属性 | 属性名 | 含义 | 示例值 | | : | : | : | | | 动画名称 | | | | 持续时长 | 、 | | | 速度曲线 | / / / | | | 延...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录