当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第一章 层叠、优先级与继承(已完结)
- 1.1 层叠
- 1.2 继承
- 1.3 特殊值
- 1.4 简写属性
- 1.5 CSS 渐进式增强技术
- 1.6 本章小结
- 第二章 相对单位(已完结)
- 2.1 相对单位的威力
- 2.2 em 与 rem
- 2.3 告别像素思维
- 2.4 视口的相对单位
- 2.5 无单位的数值与行高
- 2.6 自定义属性
- 2.7 本章小结
- 第三章 文档流与盒模型(已完结)
- 3.1 常规文档流
- 3.2 盒模型
- 3.3 元素的高度
- 3.4 负的外边距
- 3.5 外边距折叠
- 3.6 容器内的元素间距问题
- 3.7 本章小结
- 第四章 Flexbox 布局(已完结)
- 4.1 Flexbox 布局原理
- 4.2 弹性子元素的大小
- 4.3 弹性布局的方向
- 4.4 对齐、间距等细节处
- 4.5 本章小结
- 第五章 网格布局 ✔️
- 5.1 构建基础网格(已完结)
- 5.2 网格结构剖析 (上篇,已完结)
- 5.2.1 网格线的编号(下篇,已完结)
- 5.2.2 网格与 Flexbox 配合(下篇,已完结)
- 5.3 两种替代语法 ✔️
- 5.3.1 命名网格线 ✔️
- 5.3.2 命名网格区域 ✔️
- 5.4 显式网格与隐式网格(精译中 ⏳)
文章目录
- 5.3 两种替代语法 Alternate syntaxes
- 5.3.1 命名网格线 Naming grid lines
- 5.3.2 命名网格区域 Naming grid areas
《CSS in Depth》新版封面
译者按
上一节我们学习了网格线的编号和页面元素与网格单元的定位方法,然后探讨了网格布局与 Flexbox 布局的区别与联系。这一节再来看看网格布局的另外两种灵活且强大的写法。
5.3 两种替代语法 Alternate syntaxes
布局网格元素还有另外两个替代语法:命名网格线与命名网格区域,具体选用哪种写法视个人喜好而定。在某些设计中,一种语法可能较另一种更好理解。本节将分别介绍这两种语法。
5.3.1 命名网格线 Naming grid lines
有时候记录所有网格线的编号未免过于繁琐,尤其是在网格轨道很多的时候。为了能简单点,可以给网格线命名,并在布局时使用该名称而非其编号。定义网格轨道时,可以在任意两个轨道间添加一对中括号,写上网格线的名称,如以下代码片段所示:
grid-template-columns: [start] 2fr [center] 1fr [end];
这条声明定义了一个双列布局的网格,同时命名了三条垂直网格线,分别为 start
、center
和 end
。之后就可以用这些名称来声明网格元素放置的位置,不用再去数网格编号了。例如:
grid-column: start / center;
上述声明将网格元素放置在了 1 号网格线(即 start
)与 2 号网格线(即 center
)这间的区域。此外,同一网格线还可以有多个名称,如以下声明所示(这里对代码做了换行处理,以增强可读性):
grid-template-columns:
[left-start] 2fr
[left-end right-start] 1fr
[right-end];
该声明中,2 号网格线既叫作 left-end
又叫作 right-end
,使用时任选其一即可。这里还有一个设置技巧:将网格线命名为 left-start
和 left-end
,相当于定义了一个位于二者之间的、名称为 left
的区域。这里的后缀 -start
与 -end
某种意义上充当了声明该区域的关键字。如果给网格元素设置 grid-column: left
,则指定了一个从网格线 left-start
延展到 left-end
的区域。
使用命名网格线来布局示例页的新样式代码,如代码清单 5.6 所示,效果与代码清单 5.4 相同。按以下代码更新示例页面:
代码清单 5.6 使用命名网格线实现的网格布局代码
.container {
display: grid;
grid-template-columns:
/* 分别给每条垂直网格线命名 */
[left-start] 2fr
[left-end right-start] 1fr
[right-end];
/* 将水平网格线命名为 row */
grid-template-rows: repeat(4, [row] auto);
gap: var(--gap-size);
max-inline-size: 1080px;
margin-inline: auto;
}
header,
nav {
grid-column: left-start / right-end;
grid-row: span 1;
}
.main {
grid-column: left; /* 跨越 left-start 到 left-end 之间的区域 */
grid-row: row 3 / span 2; /* 从第三个命名网格线 row 开始放置元素,并跨越两个网格轨道 */
}
.sidebar-top {
grid-column: right; /* 跨越 right-start 到 right-end 之间的区域 */
grid-row: 3 / 4;
}
.sidebar-bottom {
grid-column: right; /* 跨越 right-start 到 right-end 之间的区域 */
grid-row: 4 / 5;
}
上述样式利用手动命名的垂直网格线,将每一个元素放置在相应的网格列内;而水平网格线的命名则是由 repeat()
函数实现的,最终这些水平网格线除了最后一条外,其余都被命名为了 row
。这看起来可能很奇怪,但像这样重复使用同一个名称来命名也是有效的。这样一来,main
元素就被放置在了从 row 3
开始的位置(即第三条名为 row
的水平网格线),并由此(沿垂直编码方向向下)跨越两个网格轨道。
DIY 补充说明:关于
repeat(4, [row] auto)
的含义根据命名网格线的定义,具体的名称要写在任意两个网格轨道之间,所以这里的
repeat(4, [row] auto)
展开后相当于[row] auto [row] auto [row] auto [row] auto
。由此可见,repeat()
函数定义了四个网格轨道行,每行宽度均为auto
,并且每行“顶部”的那条网格线都被命名为了row
。起初学到这里时,我曾将auto
理解成了网格线名称的默认值,是不对的。正确的理解是将auto
视为网格轨道。如下图 Chrome 浏览器的开发者工具所标注的网格所示:补图1 除了最后一条水平网格线,其余都被命名为 “row”
补图2 实测 Chrome 浏览器对左上角两个不同方向的命名网格线分别做了标注,并用箭头符号加以区分
命名网格线的用法数不胜数,具体怎么用,还要结合每个网格特定的结构才能确定。比如实现一个如图 5.10 所示的布局效果:
图 5.10 网格元素放置的位置为:从第二个名为“col”的网格线开始,向右横跨两个网格轨道的位置(即 col 2 / span 2)
该场景展示了另一种重复模式的写法:网格列按每两列为一组,然后对每组前方那条垂直网格线统一命名(即 grid-template-columns: repeat(3, [col] 1fr 1fr)
),接着再用命名的网格线将元素定位到第二组网格列上(即 grid-column: col 2 / span 2
)。
5.3.2 命名网格区域 Naming grid areas
另一个替代语法是对网格区域进行命名。该语法既不用去数网格线的编号,也不用对网格线命名;定位元素时直接将其关联到命名的网格区域中即可。使用时需要借助另外两个属性的共同参与,即 网格容器 的 grid-template-area
属性和 网格元素 的 grid-area
属性。
代码清单 5.7 给出了该写法的一个示例。最终的布局效果还是跟之前的示例页(即代码清单 5.4 和 5.6)完全一样。它是一种替代语法。根据如下代码更新示例页:
代码清单 5.7 使用命名的网格区域
.container {
display: grid;
grid-template-areas:
/* 将每个网格单元分配到一个命名的网格区域中 */
"title title"
"nav nav"
"main aside1"
"main aside2";
grid-template-columns: 2fr 1fr; /* 跟之前一样定义网格轨道的尺寸大小 */
grid-template-rows: repeat(4, auto); /* 跟之前一样定义网格轨道的尺寸大小 */
grid-gap: var(--gap-size);
max-inline-size: 1080px;
margin-inline: auto;
}
header {
grid-area: title; /* 将每个网格元素放到一个命名的网格区域 */
}
nav {
grid-area: nav; /* 将每个网格元素放到一个命名的网格区域 */
}
.main {
grid-area: main; /* 将每个网格元素放到一个命名的网格区域 */
}
.sidebar-top {
grid-area: aside1; /* 将每个网格元素放到一个命名的网格区域 */
}
.sidebar-bottom {
grid-area: aside2; /* 将每个网格元素放到一个命名的网格区域 */
}
grid-template-area
属性使用了一种类似 ASCII 字符画风格(ASCII art
) 的语法,可以直接在 CSS 中绘制出一个可视化的网格示意图。声明中给出了一系列带引号的字符串,每个字符串分别代表网格中的某一行,其中各列则用空格分隔。
本例中,第一行全部分给了网格区域 title
,第二行则给了 nav
;接下来的两行,左边一列分给了主区域 main
,右边侧边栏的两个子板块则分别分配给了 aside1
和 aside2
。就这样,每个网格元素通过 grid-area
属性被放置到了对应的命名区域中。
警告
每个命名的网格区域必须组成一个矩形,CSS 不允许出现更复杂的形状,例如
L
形或U
形。
还可以用句点(.
)作为名称,这样就能空出相应的网格单元。例如下面的样式声明,其中定义了四个网格区域,它们都环绕在中间那个留白的网格单元周围:
grid-template-areas:
"top top right"
"left . right"
"left bottom bottom";
鉴于网格布局设计了三种语法,即带编号的网格线、命名网格线、命名网格区域,在构建网格布局时,就选那个用得最顺手的语法即可。最后一个是众多开发者的最爱,特别是在明确知道每个网格元素的位置的情况下,这种写法的优势尤为明显。
关于《CSS in Depth》(中译本书名《深入解析 CSS》)
第 1 版 | 第 2 版 | |
---|---|---|
读者评分 | 原版:4.7(亚马逊);中文版:9.3(豆瓣) | 原版:5.0(亚马逊);中文版:暂无,待出版 |
出版时间 | 原版:2018 年 3 月;中文版:2020 年 4 月 | 原版:2024 年 7 月;中文版:暂无,待出版 |
原价 | 原版:$44.99;中文版:¥139.00 | 原版:$59.99;中文版:暂无,待出版 |
现价 | 原版:$36.49;中文版:¥52.54 起步 | 原版:$52.09;中文版:暂无,待出版 |
原版国内预订 | 起步价 ¥461.00 | 起步价 ¥750.00 |
本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!