2022年不能再错过 CSS 网格布局了
时至今日,可用于现代 Web 布局的特性非常的多,可能大家最为熟知的还是 Flexbox,都觉得 Flexbox 布局可以一把梭。虽然说 Flexbox 布局已非常强大了,但他始终还是一维布局,对于一些二维布局的场景,他还是有很大的极限性。这也从侧面说明现代Web布局中或未来的布局方案中还是离不开 CSS Grid,毕竟到目前为止,他是唯一一个支持二维布局的技术。在 2021 年我花了几个月的时间,涉及到 CSS Grid 的都理了个遍,通过二十多篇文章来阐述 CSS Grid。可以说,这个系列算得上是全网较为系统介绍 CSS Grid 的了。如果我还未接触过,或对 CSS Grid 有一定的恐惧,那么这个系列值得你花时间阅读。
CSS 网格中重要术语
任何一个功能模块都有自己的专业术语,CSS Grid 也不例外,只不过 CSS Grid 的技术术语涉及范围更多。在这篇文章中,详细阐述了 CSS Grid 中的相关术语,比如网格轴、网格容器、网格项目、网格线、网格单元格、网格轨道、网格区域、显式网格、隐式网格、网格间距(网槽)、子网格和嵌套网格等。
网格属性和尺寸
对 CSS Grid 布局相关技术术语有了一定了解之后,就可以开始真正的了解可用于 CSS Grid 中的属性了。在这一节中,主要和大家一起探讨可用于网格容器的属性,以及设置网格容器、网格项目的尺寸。为此我们就可以使用grid-template-columns
、grid-template-rows
和grid-template-areas
等属性定义一个显式网格。
网格轨道尺寸的设置
在 CSS Grid 中可以显式使用 grid-template-columns
和 grid-template-rows
可以显式定义网格轨道。不过在这一节中,我们主要和大家探讨可运用于网格轨道尺寸设置的单位,尤其是深度探讨了 CSS Grid 中自己独有的单位 fr
。
使用内在尺寸定义网格轨道尺寸
在 grid-template-columns
和 grid-template-rows
除了可以使用长度单位(<length>
)、百分比单位(<percentage>
) 以及弹性因子单位(fr
)设置网格轨道尺寸之外,还可以使用一些关键词(比如,none
、auto
、min-content
、max-content
、fit-content
和 fit-content()
)来设置网格轨道尺寸。其中min-content
、max-content
、fit-content
也被称为使用内在尺寸来设置网格轨道尺寸。
网格中的可用函数
grid-template-columns
和 grid-template-rows
中除了使用固定长度值、动态值和一些关键词来设置网格轨道的大小(即,使用外在尺寸和内在尺寸来设置网格轨道尺寸)。我们还可以在 CSS Grid 中使用一些函数,比如 minmax(min, max)
、repeat()
以及 CSS 的比较函数(比如min()
、max()
和 clamp()
等函数)设置网格轨道尺寸,甚至这些函数还可以相互嵌套。
显式网格和隐式网格
使用 grid-template-columns
、grid-template-rows
和 grid-template-areas
可以显式定义一个显式网格。除此之外,还可以使用 grid-auto-columns
、grid-auto-rows
和 grid-auto-flow
来定义一个隐式网格。
网格项目的自动放置
在 CSS Grid 布局中,在网格项目上使用 grid-row
、grid-column
和 grid-area
等属性可以明确地把网格项目放置在网格中的指定位置上。除此之外,CSS Grid 布局规范还包含了另外一组规则,用来约定未被明确指定位置的网格项目该如何放置。即使用 grid-auto-flow
来设置网格自动放置。
网格布局中的网格线
在 CSS 网格系统中,网格线是一个非常重要的概念。默认情况之下,只要定义了一个网格系统,就会默认创建以数字为索引号的网格线名称(行网格线名称和列网格线名称)。除此之外,还可以在 grid-template-columns
和 grid-template-rows
中显式的在中括号[]
中给网格线指定名称。前面提到过,CSS 网格系统中有显式网格和隐式网格之分,同样的,网格线也有显式网格线和隐式网格线之分,位于显式网格上的网格线被称为显式网格线,位于隐式网格上的网格线被称为隐式网格线。而且在网格系统中,明确放置网格项目时离不开网格线,换句话说,网格线命名的好不好直接会影响我们网格项目放置。在这篇文章中将主要和大家探讨网格线怎么命名?感兴趣的请继续往下阅读。
网格线在网格布局系统中是很重要的。前面的内容中虽然没详细的阐述网格布局系统中网格线的相关的知识,但不难发现,网格容器中的 grid-template-columns
、grid-template-rows
、grid-template-areas
、grid-auto-columns
、grid-auto-rows
、grid-auto-flow
等属性都会创建网格线,并且网格项目上的grid-column
、grid-row
和 grid-area
可以通过网格线来放置网格项目,而且在创建布局系统时还会带来更多的可能性。在这一节中,我们将深入探讨论在 CSS 网格布局中命名网格的各种方法,以及由此产生的一些有趣的可能性。
放置网格项目
CSS Grid 中除了可以自动放置网格项目(一般使用grid-auto-rows
、grid-auto-columns
和grid-auto-flow
)之外还可以在网格项目是显式使用 grid-row
、grid-column
和 grid-area
设置网格线名称,来明确的放置网格项目。
网格项目自动放置算法
在 CSS 网格布局中,我们可以有很多种方法将网格项目明确的放置到指定的位置。比如:
- 使用
grid-row-start
、grid-row-end
、grid-column-start
和grid-column-end
指定网格线名称,放置网格项目 - 使用
grid-row-start
、grid-row-end
、grid-column-start
和grid-column-end
的简写属性grid-row
和grid-column
指定网格线名称,放置网格项目 - 使用
grid-area
指定网格名称 或 指定grid-template-areas
定义的网格区域名称,放置网格项目 - 在
grid-row-start
、grid-row-end
、grid-column-start
、grid-column-end
或grid-row
、grid-column
指定网格线名称,并且使用span
来指定合并的网格单元格。他们的结合来放置网格项目 - 在
grid-row-start
、grid-row-end
、grid-column-start
、grid-column-end
(以及其简写属性grid-row
、grid-column
)或grid-area
中指定grid-template-rows
、grid-template-columns
和grid-template-areas
定义的网格线名称,放置网格项目 - 使用已命名的网格线名称和
span
关键词,放置网格项目 - 在
grid-area
指定grid-template-areas
或grid-template-rows
和grid-template-columns
创建的网格区域名称,放置网格项目
不过,在网格布局系统中,网格项目的放置是有自己一套成熟的算法。在这个章节中,我们分为五个步骤和大家一起聊聊 CSS Grid 网格项目放置(自动放置和明确放置)的算法。
网格项目的重叠和z轴的层级
网格项目可以使用grid-row
、grid-column
和 grid-area
等属性根据网格线名称明确指定网格项目位置。这样就可以让网格项目相互重叠。换句话说,在 CSS Grid 中,可以使用下面这几种方式让网格项目相互重叠:
- 使用网格线索引号
- 使用命名的网格线
- 使用命名的网格区域
- 合并网格单元格(即,跨越网格项目)
更为有趣的是,CSS 网格项目不需要显式设置position
为非static
的值就会触发z-index
生效,也就是说,在网格项目重叠时,可以直接在网格项目上显式设置z-index
来控制网格项目在z
轴的层级。
网格布局中的对齐方式和间距
如果你熟悉 Flexbox 布局中的对齐方式的话,那么 CSS Grid 中的对齐方式就很容易掌握。因为它和Flexbox是非常相似的,都是使用 CSS Box Alignment Module Level 3 规范中的特性。在这个章节中,详细介绍了网格布局中网格项目和网格轨道的对齐方式,除此之外,还介绍对齐和margin
的关系(如何使用margin
来设置网格项目的对齐方式)。
另外,在文章的末尾,还介绍了gap
属性,即如何使用gap
来设置网格轨道之间的间距(俗称网槽的大小)。
网格项目的宽高比
这一章节中主要和大家一起探讨了网格项目的宽高比的设置,即 CSS 的aspect-ratio
属性在网格中的运用。另外,还介绍了padding-top
或padding-bottom
以及CSS 自定义属性和calc()
函数如何实现网格项目的宽高比。
网格中的书写模式
在这篇文章中主要和大家聊了聊 CSS的逻辑属性 以及 CSS 的书写模式 对网格布局的影响。比如说,网格项目自动放置和书写模式的关系、基于网格线放置网格项目和书写模式的关系以及网格区域与书写模式的关系等。
嵌套网格 vs. 子网格
一段时间以来,关于subgrid
的使用情况、如何实现它的问题有很多讨论,甚至还有一些关于是否需要它的辩论。很多讨论都是围绕着另外两种可以处理许多与subgrid
相同问题的方法:嵌套网格 和 display: contents
。这篇文章由嵌套网格作为切入口,并深入阐述嵌套网格和subgrid
,即我们将了解哪些是相似的,哪些是subgrid
与嵌套网格区别?以及阐述在一些非常有效的情况下,子网格是真正需要的,而在另一些情况下,它并不是严格需要的,但会带来一个更简洁的解决方案。
subgrid vs display: contents
subgrid
进入 CSS Grid 布局模块的 Level 2 规范之前,嵌套网格、subgrid
和 display: contents
就有深度的讨论,最终 subgrid
得到更多的支持,也最终成为规范中的一部分。也就是说,嵌套网格 和 display: contents
都可以实现类似 subgrid
的布局。那这个章节中,和大家来探讨 display: contents
和 subgrid
有何差异?
瀑布流布局
自从多列布局、Flexbox布局和Grid布局得到浏览器支持之后,就可以使用这些特性来实现 瀑布流的布局 ,但这些技术实现的瀑布流布局都或多或少存有一定的缺陷。不过,值得庆幸的是,CSS 网格布局的第3级(CSS Grid Layout Module Level 3) 将真正的瀑布流布局纳入了 W3C 规范中,称得上真正的瀑布流布局。不过遗憾的是,支持该规范草案的主流浏览器并不多,只有Firefox 和 Firefox Nightly。虽然这个功能还不能用于实际生产中,但你的试用以及使用之后的反馈是很有价值的,这有助于确保它满足你对这种布局的要求。
网格审查器调式网格布局
从前面这些内容,不难发现网格布局的复杂性,灵活性。我想大家也意识到了,CSS Grid到来之后,Web中设计布局的方法也已经改变了。我们可以在纸上绘制布局草图,思考布局设计的全部内容。当你开始敲击代码的时候,就已经知道布局会是什么样子。正因为CSS Grid布局的复杂性,再加上网格容器上定义的网格是不可见的。为此我们不得不考虑,如何更轻易的使用网格,或者碰到网格布局相关的 Bug,又应如何来调试。熟悉 Web 开发的同学都知道,在调试布局或CSS相关的问题时,喜欢在元素上添加一个边框。在网格布局中,虽然可以使用类似的方法在网格容器和网格项目中添加边框,帮助我们快速的定位;但是我们没法给网格线添加边框。不过庆幸的是,目前主流的浏览器,比如 Chrome、Firefox、Safari 和 Microsoft Edge 浏览器的开发者工具(DevTools)都提供了网格布局审查器。有了这些工具之后,可以快速的帮助我们使用网格,调试使用网格碰到的问题。
网格布局案例与特征
CSS Grid 模块的出现以及浏览器对其支持,为 Web 布局提供了前所未有的可能性。我们可以用更少的元素(更简洁的 HTML 结构)构建更复杂的设计。这比我们一直认为非常强大的 Flexbox 要更强很多。但是,当你想到 CSS Grid 时,你一般会想到是我们平时习以为常的方块布局,对吗?@Andy Barefoot 在他的个人网站 和 Codepen 上提供了很多有创意的响应式布局效果,让你会对 Web 布局有一种焕然一新的感觉,感觉与你的经典 Web 设计(规规矩矩方块布局),而且他使用了 CSS Grid 布局来做到这一点。
使用网格构建建重叠布局
在 CSS Grid 布局中,我们可以通过网格项目放置的方式,让不同的元素重叠在一起,并且通过 CSS 的 z-index
来控制网格项目在 z
轴上的层叠顺序。也就是说,以往需要使用 CSS 的 position
的绝对定位(absolute
)来实现的布局,现在可以直接使用 CSS Grid 来解决。在这个案例中,我们主要来看如何使用 CSS Grid 实现元素叠加的布局效果。
使用网格构建Full-Bleed布局
Full-Bleed 是印刷界中的一个概念,被称为 全出血,即在印刷中,我们有出血量,这是纸张被修剪的地方以外的区域。正因如此,印刷设计师习惯于在设计工作中考虑出血量。我们通过设置安全区域来做到这一点。这几年,这种被称为“全出血”的概念也运用到 Web 的布局中。就是在受限宽度的一列中使用全宽元素的布局,比如在较窄的一列文本中使用一个边缘到边缘的图像。在社区中,也有人把这种布局效果称为 Full-Width 布局,也有人称为 Edge-To-Edge 布局。说实话,在Web中实现这种布局效果,已不是难事,社区中有很多种不同的技术方案,都可以达到这个布局效果。不过,今天我们以不同的角度来思考这个问题!
使用网格构建交叉布局
这个案例是介绍 CSS Grid 构建的另一种网格布局,即 交叉布局。通过这个案例来更好的帮助我们更进一步理解 CSS Grid 的相关属性在实际中(Web 布局)如何使用。
使用网格构建杂志报刊类布局
一直以来,在 Web 布局中都是以方方正正的矩形向用户展示 UI 效果,而且众多 Web 开发者的意识中也是如此,Web 的布局是无法打破矩形排列的限制!但 Web 技术的发展速度是惊人的,每天都有新的东西出现在我们的眼前。就在这短短的几年时间内,用于 Web 布局的新特特别的多。换句话说,如果今天设计师跟你说:“亲,整一个类似杂志或报刊类的布局吧”!你会爽快的说 OK! 即,使用现在的新特性可以打破矩形框的限制,让你在 Web 上实现像杂志一样的排版布局。
小结
这个系列是 图解CSS 系列中关于 CSS 网格的部分,正如上面所列。整个系列共有二十多篇内容,涉及理论的部分有近十八篇,案例部分有近五篇,耗时半年。整个系列使用了上百张图片和近百个示例来阐述。个人认为这个系列是全网中最全面,最详细的介绍 CSS 网格的系列教程。希望这些教程对你有所帮助。