当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 【第三部分 现代 CSS 代码组织】 ✔️
- 【第八章 层叠图层及其嵌套】 ✔️
- 8.1 用 layer 图层来操控层叠规则(上篇) ✔️
- 8.1.1 图层的定义(上篇) ✔️
- 8.1.2 图层的顺序与优先级(精译中 ⏳)
- 8.1.3 revert-layer 关键字
文章目录
《CSS in Depth》新版封面
译者按
从本篇开始,我们将进入本书第三部分、同时也是新版中全新增补的第8章——CSS 层叠图层(cascade layer)的学习。为了译好这章内容,我还上网提前预习了好几个同样介绍 CSS layer 图层的文章与视频资源,对比下来都没有书中介绍的内容全面且通俗易懂。对于初学 CSS 的朋友而言当真是有福气。让我们在作者的带领下,一起拿下这块新的 CSS 高地!
第三部分 现代代码组织 Modern code organization
代码是一种交流:不仅是与计算机之间的交流,也是与使用代码的其他开发人员的交流。掌握浏览器如何渲染 CSS 很重要,了解如何在项目中编写和组织 CSS 同样也很重要。在这一部分(第 8 章到第 10 章),我们将介绍最近添加到 CSS 语言中的一些工具,它们可以提供更明确的层叠控制,并有助于代码的整体组织;同时还将向您展示如何编写 CSS,使其条理清晰,便于日后维护。
第八章 层叠图层与嵌套 Cascade layers and nesting
本章概要
- 按合理的逻辑组织 CSS
- 用图层(layers)来控制层叠行为
- 伪类
:is()
与:where()
的使用- 通过嵌套对相关样式进行分组
在本书第一部分(译注:即第 1 ~ 3 章)和第二部分(译注:即第 4 ~ 7 章)中,我们了解了 CSS 的复杂性,学习了 CSS 在布局页面元素方面提供的各类工具,并先后将盒模型(box model)、外边距折叠(margin collapsing)、堆叠上下文(stacking contexts)、Flexbox 布局以及网格布局等工具收入囊中。这些技能会在您的项目开发中、尤其是在刚启动一个新项目的时候派上用场。然而,在软件开发领域,编程并不仅仅只是为了让代码运行起来,与之同等重要的,是用易于理解的方式来组织代码,以便后续进行更改时代码不会变得脆弱不堪。具体到 CSS 中,这将带来一系列全新的困难与挑战。
在过去,开发人员应对这些问题的唯一方法,就是遵循严格规定的方法论与命名规范;而如今,CSS 提供了全新的功能来打破这一僵局。这些一流的功能设计为代码组织提供了更为理想的解决方案,并成功实现了对层叠(cascade)更为明确的控制。
本书第 3 部分将重点介绍这些功能特性,教会您通过它们来驾驭上述问题的要领,并带您了解 CSS 架构相关的知识。这些章节与其他章节略有不同,论述的重点不再是样式表中的某些具体声明,而是更侧重于所选的选择器,以及优先显示目标样式所涉及的层叠操作。此外,我还将站在更高的层面带您审视样式表的整体结构,使其条理清晰、易于理解。
尽管这些工具适用于任何规模的项目,但它们主要用于应对网站或应用在规模与复杂性日益增长的情况下出现的这些问题。这才是它们真正的用武之地。
由于这些章节中的很多功能都是 CSS 的最新特性,其中部分功能可以直接现学现用,而另一部分的成熟应用可能还尚需时日。撰写本书时,我对未来始终持乐观态度,希望它们都能在不久的将来成为新的惯例。虽然在介绍每一项新功能时,我都会指出当前浏览器的支持情况,但在阅读本书时,请务必查看最新的统计数据。这里推荐两个挺不错的参考资源:https://developer.mozilla.org/ 和 https://caniuse.com/。
8.1 用 layer 图层来操控层叠规则 Manipulating the cascade with layers
说起 CSS 的层叠规则,浏览器会简单地对样式应用一系列规则,以确保在两个规则集恰巧应用到同一元素时,其中一个规则集能根据既定规则覆盖掉另一个。选择器的优先级与源码顺序是解决样式冲突的一种可靠途径;但有时它们也未必能准确传达开发者在 CSS 优先级上的真实意图。在设计样式表时,有个很常见的场景是希望优先级较低的规则集胜出。例如,大多数样式表都会通过以下 CSS 代码来设置页面链接的基础样式:
a:any-link {
color: var(--brand-blue);
font-weight: bold;
}
该链接选择器包含一个标签与一个伪类,其优先级为 0, 1, 1
;而在页面的其他位置可能有个下面这样的链接,被设计成了一个大型的引导按钮:
<a class="button" href="/about">Read more</a>
要是想通过普通的 .button
选择器来设置按钮样式,此时就会遇到问题:该选择器的优先级为 0, 1, 0
,低于 a:any-link
的 0, 1, 1
。因此 .button
中的任何样式都无法覆盖上述基础样式中的字体颜色和加粗效果。解决这一问题的传统方法是调整其中一个选择器的优先级,或者两个同时调整,以达到期望的效果。
8.1.1 图层的定义 Defining layers
针对上述问题,现代 CSS 采取的更为有效的管理方式是使用 层叠图层(cascade layers) 1。层叠图层 是层叠规范新增的一项标准,它能将样式划分到一系列称为 图层(layers) 的分组结构中;而这些图层的优先级顺序可以任意指定。这样一来,图层 A 内的所有样式就可以无视选择器中的优先级顺序,始终先于图层 B 中的样式进行显示。
层叠图层 早在 2022 年初就开始在所有的主流浏览器中发布,因此得到了相当广泛的支持。不过保险起见,还是应该访问 https://caniuse.com/css-cascade-layers 来查看最新的浏览器支持情况。由于层叠图层很难在不支持该功能的浏览器中实现优雅降级,对于一小部分用户而言,可能会因为无法立即更新浏览器而无缘体验层叠图层带来的便利——旧版浏览器将忽略图层内的所有样式规则。
根据您阅读本文的时间和目标受众的不同,这样的不兼容问题可能可以接受,也可能接受不了。因此在决定是否启用层叠图层时,请务必查看最新的浏览器兼容性情况。如果非要启用图层,却又担心浏览器存在兼容性问题,可以参考这篇文章给出的替代方案:https://mng.bz/z89w,了解更多可用于模拟 CSS 图层效果的工具详情。
图 8.1 为两个来自不同层叠图层的样式效果。无论选择器的优先级如何,位于高优先级图层中的任何样式都将覆盖低优先级图层中的样式。本例中,选择器 .button
中的样式位于优先级更高的图层,因此将覆盖位于低优先级图层的、由选择器 a:any-link
指定的样式声明。
【图 8.1 优先级较高的图层中的样式,将覆盖优先级较低的图层中存在冲突的样式声明】
图层(Layers) 的定义通过 @规则中的 @layer
来实现。图层上的样式则写在相应的 @layer
规则的大括号内,如代码清单 8.1 所示。该样式代码定义一个全局图层(global layer)和一个主题图层(theme layer)。由于样式表中后定义的图层优先级将 高于 先定义的图层,因此,当页面样式存在冲突时,主题图层内的样式声明将优先于全局图层进行渲染,而与选择器原有的优先级无关。
代码清单 8.1 层叠图层的样式语法示例
@layer global { /* 定义一个全局图层 */
/* 以下均为该全局图层所属样式 */
:root {
--brand-blue: #0063cc;
}
a:any-link {
color: var(--brand-blue);
font-weight: bold;
}
}
@layer theme { /* 定义一个主题图层 */
/* 以下均为该主题图层所属样式 */
.button {
display: inline-block;
padding: 0.5rem;
color: white;
background-color: var(--brand-blue);
font-weight: normal;
text-decoration: none;
}
}
因此,<a class="button">
元素最终将按常规粗细、蓝底白字进行渲染。
在层叠顺序上,层叠图层位于样式表来源(origin)及行内样式(inline styles)之后、选择器优先级(specificity)之前。同一图层内,所有的常规优先级规则仍然适用。图 8.2 给出了第 1 章中曾经介绍过的 CSS 层叠顺序示意图。图中清晰展示了作用于同一元素上的、两个相互冲突的样式声明在先后顺序上的判定过程。
【图 8.2 在层叠规则的顺序判定中,层叠图层位于选择器优先级的前面】
警告
未在层叠图层中定义的样式将优先于图层中的样式。这些样式可以理解为位于自身固有的最高优先级图层内。
您还可以对层叠图层命名。图层名称可以是由字母或数字字符(alphanumeric characters)、连字符(hyphens)及下划线(underscores)构成的任何有效标识符;图层名称不能以十进制数字开头;除此之外的任何字符都必须用反斜线进行转义(如 @layer theme\$
)。也就是说,您可以根据具体情况为层叠图层进行命名并构建出相应的结构来。稍后我将介绍一个常用模式(common pattern)来对这些命名图层进行合理组织。
1 匿名图层 Anonymous layers
层叠图层也可以不用命名。如果省略图层名称,则默认创建了一个 匿名图层(anonymous layers)。代码清单 8.2 给出了代码清单 8.1 的匿名图层版本,二者效果相同。
代码清单 8.2 匿名层叠图层的写法
@layer { /* 第一个匿名图层 */
:root {
--brand-blue: #0063cc;
}
a:any-link {
color: var(--brand-blue);
font-weight: bold;
}
}
@layer { /* 第二个匿名图层 */
.button {
display: inline-block;
padding: 0.5rem;
color: white;
background-color: var(--brand-blue);
font-weight: normal;
text-decoration: none;
}
}
上述代码中,第二个图层仍然优先于第一个图层,因为前者是在样式表的后面定义的。
在只需要几个图层的简易网站中,采用匿名图层可能也没什么问题,但通常不推荐这种方案。图层名称有利于该图层的反复引用,以便在不同位置对同一图层设置样式。因此,命名图层的灵活性通常会比匿名图层更高,稍后会演示说明。另外,图层名称在传达各个图层的意图(purpose)方面也有可圈可点之处,可以进一步增强代码的逻辑性。
说明
在使用 @规则中的
@import
来导入外部样式表时,也可以将目标样式表指定给某个图层。例如,使用@import "bootstrap.css layer(bootstrap);"
就能将样式表bootstrap.css
导入到一个名为bootstrap
的图层中,效果上就如同将导入的样式表所有内容都放进@layer
规则中一样;但通过 HTML 的<link>
标签来关联样式表时,可惜还没有类似的写法。如果非要在 HTML 中通过这种方式直接导入 CSS 样式,可以考虑在<style>
标签中使用@import
规则。
关于《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 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!
目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):
- 第一章 层叠、优先级与继承(已完结)
- 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.4.1 添加变化 (中)
- 5.4.2 让网格元素填满网格轨道(下)
- 5.5 子网格(全新增补内容)
- 5.6 对齐相关的属性
- 5.7 本章小结
- 第六章 定位与堆叠上下文(已完结)
- 6.1 固定定位
- 6.1.1 创建一个固定定位的模态对话框
- 6.1.2 在模态对话框打开时防止屏幕滚动
- 6.1.3 控制定位元素的大小
- 6.2 绝对定位
- 6.2.1 关闭按钮的绝对定位
- 6.2.2 伪元素的定位问题
- 6.3 相对定位
- 6.3.1 创建下拉菜单(上)
- 6.3.2 创建 CSS 三角形(下)
- 6.4 堆叠上下文与 z-index
- 6.4.1 理解渲染过程与堆叠顺序(上)
- 6.4.2 用 z-index 控制堆叠顺序(上)
- 6.4.3 深入理解堆叠上下文(下)
- 6.5 粘性定位
- 6.6 本章小结
- 第七章 响应式设计(已完结)
- 7.1 移动端优先设计原则(上篇)
- 7.1.1 创建移动端菜单(下篇)
- 7.1.2 给视口添加 meta 标签(下篇)
- 7.2 媒体查询(上篇)
- 7.2.1 深入理解媒体查询的类型(上篇)
- 7.2.2 页面断点的添加(中篇)
- 7.2.3 响应式列的添加(下篇)
- 7.3 流式布局
- 7.4 响应式图片
- 7.5 本章小结
本书使用【层叠图层】的译法,而非网上常见的“级联层”,一来是为了和 CSS 的 C 的译法保持一致;二来是通过 层叠 来强调其对 CSS 层叠行为的干预和控制。对于 MDN 中文版文档译为“级联层”的做法,我本人持保留意见。 ↩︎