前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CSS 中的 Grid 布局 完全指南

CSS 中的 Grid 布局 完全指南

作者头像
羽月
发布2022-10-08 13:52:47
2.9K0
发布2022-10-08 13:52:47
举报
文章被收录于专栏:羽月技术羽月技术

Grid 是一个基于二维网格布局的系统,有了它我们可以非常方便的实现过去很复杂布局,无需再使用float, inline-block, position 这些本质上是 hack 的方法。

CSS网格布局擅长于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系(前提是HTML生成了这些区域)。

它像表格一样,网格布局让我们能够按行或列来对齐元素。 然而在布局上,网格比表格更可能做到或更简单。

网格布局概念

在学习之前需要了解以下网格的几个概念。

网格轨道(Grid Tracks)

网格轨道 是两条网格线之间的空间。它们通过使用属性grid-template-columnsgrid-template-rows在网格中定义。

上图中有两行三列,一行或一列就叫做轨道。

网格线(Grid Lines)

使用Grid布局在显式网格中定义轨道的同时会创建网格线。

网格线可以用它们的编号来寻址。在从左到右的语言中,列线1将位于网格的左侧,行线1将位于其顶部。线编号遵循文档的写入模式,因此在从右到左的语言中,列线1行将位于网格的右侧。下面的图片展示了该网格的线编号,假设语言是从左到右的。

网络单元格(Grid Cell)

Grid布局中,网络单元格是 CSS 网格中的最小单元。它是四条网格线之间的空间,非常像表格单元格。

网格区域(Grid Areas)

网格区域是网格中由一个或者多个网格单元格组成的一个矩形区域。本质上,网格区域一定是矩形的。例如,不可能创建T形或L形的网格区域。

网格间距(Gutters)

网格间距是网格轨道之间的间距,可以通过grid-column-gapgrid-row-gap在Grid布局中创建。

使用 Grid 布局

和 flex 类似,要使用网格布局,首先要有一个容器,将一个元素的display设置为grid就可以得到一个 grid 容器。容器的子项就是网格项(grid items),它有点类似table中的td,但是更加灵活。

float, clear, 和 vertical-align 元素对网格容器不起作用。

容器上的属性

网格模板

创建了网格容器,我们就可以定义这个网格有多少行有多少列,并且每一行每一列的大小。

grid-template-rows

我们使用grid-template-rows来显性定义网格有多少行。它可以取如下的值:

  1. none 关键字,表示不明确的网格。所有的行和其大小都将由grid-auto-rows 属性隐式的指定。
  2. 非负值的长度大小:如px, em, vw
  3. 百分比:相对于网格容器的,如果是inline-grid,则百分比值将被视为auto
  4. flex:非负值,用单位fr来定义网格轨道大小的弹性系数。每个定义了flex 的网格轨道会按比例分配剩余的可用空间
  5. max-content关键字,表示以网格项的最大的内容来占据网格轨道的
  6. min-content关键字,表示以网格项的最大的最小内容来占据网格轨道
  7. auto如果该网格轨道为最大时,等同于max-content,为最小时,等同于 min-content

grid-template-columns

它和grid-template-rows类似,一个设置网格行,一个是设置网格列。

代码语言:javascript
复制
.container {    display: grid;    grid-template-columns: 40px 50px auto 50px 40px;    grid-template-rows: 25% 100px auto;
}
代码语言:javascript
复制
.container {  display: grid;  grid-template-columns: 1fr 1fr 1fr;  grid-template-rows: 100px 100px;
}

Grid 中可以使用的函数

在 Grid 布局中我们还可以使用如下 3 个函数

repeat()

repeat函数可以以一种更简洁的方式去表示大量而且重复行的表达式。

比如上面grid-template-columns: 1fr 1fr 1fr;我们可以写成repeat(3, 1fr)。它的第一个参数是重复的次数,而可以为auto-fillauto-fit

auto-fill

如果容器有明确的大小或最大大小,则重复次数是最大可能的正整数,不会导致网格溢出其网格容器。如果任何重复次数都会溢出,则重复次数为1。

auto-fit

auto-fill的行为相同,只是在放置网格项后,任何空的重复轨道都会折叠。

代码语言:javascript
复制
#container {  display: grid;  grid-template-columns: repeat(2, 50px 1fr) 100px;  grid-gap: 5px;  box-sizing: border-box;  height: 200px;  width: 100%;  background-color: #8cffa0;  padding: 10px;
}#container > div {  background-color: #8ca0ff;  padding: 5px;
}
minmax()

定义了一个长宽范围的闭区间。它接受两个参数,最小值 和 最大值。它返回这个区间中的值。

minmax(max-content, 300px),最大不能大于300px

minmax(200px, 1fr) 最小不能小于200px

fit-content()

它相当于min(maximum size, max(minimum size, argument))。参数可以是长度值和百分比。

它在内容的最小值和参数中去一个最大值,然后再在内容的最大值中取一个最小值。

也就是当内容少时,它取内容的长度,如果内容多,内容长度大于参数长度时,它取参数长度。

grid-template-areas

这个属性网格区块,需要和grid-area配合使用,它的值可以是none字符串

为字符串时每一个给定的字符串会生成一行,一个字符串中用空格分隔的每一个单元(cell)会生成一列。多个同名的,跨越相邻行或列的单元称为网格区块(grid area)。非矩形的网格区块是无效的。

代码语言:javascript
复制
#page {  display: grid;  width: 100%;  height: 250px;  grid-template-areas: "head head"
                       "nav  main"
                       "nav  foot";  grid-template-rows: 50px 1fr 30px;  grid-template-columns: 150px 1fr;
}#page > header {  grid-area: head;  background-color: #8ca0ff;
}#page > nav {  grid-area: nav;  background-color: #ffa08c;
}#page > main {  grid-area: main;  background-color: #ffff64;
}#page > footer {  grid-area: foot;  background-color: #8cffa0;
}

grid-template-areas字符串,关联 grid item 的grid-area,用它定义一片区域。

grid-template

grid-template-rowsgrid-template-columnsgrid-template-areas的简写。

它的值可以分三种情况:

  1. none
  2. 只有定义行和列时可以使用rows/columns语法,如grid-template: 100px 1fr / 50px 1fr;
  3. 当三个都有时,也用一个/分隔,而且它的右边也还是columns,但是它的左边语法是<line-names>? <string> <track-size>? <line-names>?
代码语言:javascript
复制
.page {    grid-template: [header-top] "a a a"     [header-bottom]
                   [main-top]   "b b b" 1fr [main-bottom]
                   / auto 1fr auto;
}/*
line-names 是可选的,自定义名称,需要使用中括号包裹,它其实相当于注释
string 网格项 grid-area 的关联值
track-size 这一行的大小
*/
代码语言:javascript
复制
#page {  display: grid;  width: 100%;  height: 200px;  grid-template: [header-left] "head head" 30px [header-right]
                 [main-left]   "nav  main" 1fr  [main-right]
                 [footer-left] "nav  foot" 30px [footer-right]
                 / 120px 1fr;
}header {  background-color: lime;  grid-area: head;
}nav {  background-color: lightblue;  grid-area: nav;
}main {  background-color: yellow;  grid-area: main;
}footer {  background-color: red;  grid-column: foot;
}

grid-row-gap / row-gap

用来设置行元素之间的间隙(gutter) 大小。它的值可以是长度值、百分比和normal

CSS Grid Layout 起初是用 grid-row-gap 属性来定义的,目前逐渐被 row-gap 替代。但是,为了兼容那些不支持 row-gap 属性的浏览器,你需要使用带有前缀的属性。

代码语言:javascript
复制
.box{    grid-row-gap: 1em;
}

grid-column-gap / column-gap

用来设置元素列之间的间隔 (gutter) 大小。它的值可以是长度值、百分比和normal

normal 在 多列布局 时默认间隔为1em,其他类型布局默认间隔为 0。

grid-row-gap一样,它渐渐被column-gap取代。

代码语言:javascript
复制
.page {    grid-column-gap: 1em;
}

grid-gap / gap

是上面两个属性的简写,语法是row-gap column-gap。如果没有column-gap那么它将被设置成跟row-gap一样的的值。

它也渐渐被gap取代。

代码语言:javascript
复制
#grid {  display: grid;  height: 200px;  grid-template: repeat(3, 1fr) / repeat(3, 1fr);  gap: 20px 5px;
}#grid > div {  background-color: lime;
}

隐式创建的行和列

css gird 会根据周围项目的大小和跨度自动调整网格上每个项目的位置。

比如:

代码语言:javascript
复制
.box {  display: grid;  grid-template: 25px / 100px 160px;  background: #000;
}.box * {  background: #ccc;
}.box *:nth-child(even) {  background: #777;
}

我们只定义了一行,两列。但是我们却有 5 个子元素。CSS网格决定将它们扩展到隐式创建的空间,新建的隐式行中的列自动从先前指定的grid-template-rows属性继承行高。

grid-column-start, grid-column-end, grid-row-startgrid-row-end这 4 个属性是 grid item 上的,它可以定义一个 grid item 的位置,如果我们将它的位置设置的超出我们定义的网格,那时也会隐式创建行或列。

grid-auto-rows

指定了隐式创建行的大小。它的值可以是:

  1. 长度值px em vmax
  2. 百分比:相对于网格容器
  3. flex:非负值,用单位fr来定义网格轨道大小的弹性系数。每个定义了flex 的网格轨道会按比例分配剩余的可用空间
  4. max-content关键字,表示以网格项的最大的内容来占据网格轨道的
  5. min-content关键字,表示以网格项的最大的最小内容来占据网格轨道
  6. auto如果该网格轨道为最大时,等同于max-content,为最小时,等同于 min-content

它的值和grid-template-rows是一样的。

代码语言:javascript
复制
.box {  display: grid;  grid-template: 25px / 100px 160px;  gap: 10px 20px;  grid-auto-rows: 50px;  background: #000;
}.box * {  background: #ccc;
}.box *:nth-child(even) {  background: #777;
}

grid-auto-columns

指定了隐式创建的网格的列宽。它的取值和grid-auto-rows一样。

代码语言:javascript
复制
#grid {  height: 100px;  display: grid;  grid-template-areas: "a a";  grid-gap: 10px;  grid-auto-columns: 200px;
}#grid > div {  background-color: lime;
}

grid-auto-flow

控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。

如果我们在一个div中写几个div,再对父级设置display: grid;,从视觉的角度可以发现没什么变化。但是如果我们再将父级div加上一句grid-auto-flow: column;我们就发现现在子元素在一行显示,和弹性盒子效果差不多。

grid-auto-flow的值如下:

  1. row指定自动布局算法按照通过逐行填充来排列元素,在必要时增加新行。(默认值)
  2. column指定自动布局算法通过逐列填充来排列元素,在必要时增加新列。

在这两个关键字后面还可以加上dense关键字。语法是[ row | column ] || dense

该关键字指定自动布局算法使用一种“稠密”堆积算法,如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白。这样做会填上稍大元素留下的空白,但同时也可能导致原来出现的次序被打乱。

如果省略它,使用一种「稀疏」算法,在网格中布局元素时,布局算法只会「向前」移动,永远不会倒回去填补空白。这保证了所有自动布局元素「按照次序」出现,即使可能会留下被后面元素填充的空白。

grid-auto-flow: row;

grid-auto-flow: row dense;

grid

grid是 CSS 简写属性,它几乎包括上面提到的所有属性(除了gap)。

与其他简写属性同样,若有次级属性未被声明,其将使用初始值。另外,尽管此简写声明无法设置网格的槽(gutter),槽会被该声明重置。

它的值可以分为 3 类

grid-template

就和grid-template简写一样,如grid: [linename1] "a" 100px [linename2];

grid-template-rows / [ auto-flow && dense? ] grid-auto-columns?

grid-template-rows设置行高(grid-template-columns被设置为none),/ 后面的auto-flow必须要写(grid-auto-flow被设置为 column),最后grid-auto-columns置明确该如何自动重复列轨道(grid-auto-rows属性设为auto)。 如grid: repeat(3, [line1 line2 line3] 200px) / auto-flow 300px;

[ auto-flow && dense? ] grid-auto-rows? / grid-template-columns

这种写法和上种写法相反,这种是设置grid-template-columnsrows属性为none)。可选的设置grid-auto-rows属性(columnsauto) 如grid: auto-flow dense / 30%;

网格项上的属性

grid-row-start, grid-row-end, grid-column-start, grid-column-end

分别指定 grid item 在网格中的行起始位,行结束位,列起始位,列结束位。

这就需要了解之前介绍的网格线概念,横线(row)从上到下递增,竖线(column)从做到右递增,都是从 1 开始算。

它们可以取如下值:

  1. auto表示自动放置,自动跨度或默认span为 1
  2. 数字表示网格线
  3. span 数字表示跨越几个格子,数字小于等于0无效。如果超过网格大小会隐式创建行或列。

它和table有点相似

如果设置的位置超出指定大小,会得到不稳定的效果,应该避免这种情况。

代码语言:javascript
复制
.box {  display: grid;  grid: 100px 100px / 100px 100px;  background: #000;
}.box * {  background: #ccc;
}.box *:nth-child(even) {  background: #777;
}.box1 {  grid-column-start: span 5;
}

grid-row, grid-column

grid-rowgrid-column分别是上面 4 个属性简写。

它们值的语法是start / end。如果只有一个值那么它是startend值为默认auto

当列数未知时,可以使用-1让它一直扩展到网格末尾。

使用负值

grid-area

上面我们已经展示了grid-areagrid-template-areas结合的用法。grid-area其实是grid-row-startgrid-column-startgrid-row-endgrid-column-end的简写。

它的默认值是grid-area: auto;

如果设置了 4 个值的话那么它的顺序是

grid-area: row-start / column-start / row-end / column-end;

如果设置了 3 个值,那么最后一个为auto

如果设置了 2 个值,那么后两个为auto

如果设置了 1 个值,那么后三个为auto

如果第一项是自定义表示,那么被忽略的都为自定义表示

代码语言:javascript
复制
.box1 {  grid-area: a / a;
}/* 相当于 */.box1 {    grid-row-start: a;    grid-column-start: a;    grid-row-end: a;    grid-column-end: a;
}

网格项的内容对齐

我们可以使用align-selfjustify-self调整 grid item 的内容对齐方式。

align-self用来垂直方向对齐,justify-self用来水平方向对齐。

align-self

flex 布局也可以使用这个属性。它常用如下 3 个值:

  1. start: 内容顶端对齐
  2. center: 内容垂直居中
  3. end: 内容底部对齐

justify-self

它常用如下 3 个值:

  1. start / left: 内容左对齐
  2. cneter: 内容水平居中
  3. end / right: 内容右对齐
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 羽月技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 网格布局概念
    • 网格轨道(Grid Tracks)
      • 网格线(Grid Lines)
        • 网络单元格(Grid Cell)
          • 网格区域(Grid Areas)
            • 网格间距(Gutters)
            • 使用 Grid 布局
            • 容器上的属性
              • 网格模板
                • grid-template-rows
                  • grid-template-columns
                    • Grid 中可以使用的函数
                      • repeat()
                      • minmax()
                      • fit-content()
                    • grid-template-areas
                      • grid-template
                        • grid-row-gap / row-gap
                          • grid-column-gap / column-gap
                            • grid-gap / gap
                              • 隐式创建的行和列
                                • grid-auto-rows
                                  • grid-auto-columns
                                    • grid-auto-flow
                                      • grid
                                      • 网格项上的属性
                                        • grid-row-start, grid-row-end, grid-column-start, grid-column-end
                                          • grid-row, grid-column
                                            • grid-area
                                            • 网格项的内容对齐
                                              • align-self
                                                • justify-self
                                                相关产品与服务
                                                容器服务
                                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档