什么是图层?使用 CSS 最困难的部分之一是处理特异性。如果您尝试从像 Bootstrap 这样的框架覆盖样式,这一点尤其明显,但是随着 CSS 层的引入,这一切都发生了变化。这个新功能允许您创建自己的自定义 CSS 层,这是有史以来第一次确定所有 CSS 代码的特异性层次结构。在本文中,我将剖析这对您意味着什么,它是如何工作的,以及您今天如何开始使用它。
创建自己的自定义图层的能力对于 CSS 来说是新功能,但图层从一开始就在 CSS 中存在。CSS 中有 3 个不同的层来管理所有样式的工作方式。
- 浏览器(也称为用户代理)样式
- 用户风格
- 作者风格
浏览器样式是应用于浏览器的默认样式。这就是为什么 Chrome 和 Safari 中的按钮看起来不同的原因。在浏览器层中找到的样式在浏览器之间是不同的,并且给每个浏览器一个独特的外观。
下一层是用户样式,这并不是您真正需要担心的事情。这些通常是用户可以编写并注入浏览器的自定义样式,但浏览器不再真正支持这些样式。用户可能会更改一些浏览器设置,这些设置会向该图层添加样式,但在大多数情况下,可以完全忽略该图层。
最后,我们来到作者层。这是您最熟悉的层,因为您编写的每一段 CSS 代码都属于这一层
层叠的规则层叠的规则是按照“样式表来源”、“选择器优先级”、“源码顺序”来考虑的,下图展示了一个判定流程:
但是页面一样复杂,组件一多,样式管理起来还是很费劲,很多时候还是得用自己不想用的一些「优先级」权重高的选择器去覆写样式,比如ID或者 !important,所以CSS新出一个 @layer 特性,能让样式得到更好的管理和控制。
如何创建自己的图层大家用过ps的话,很好理解 @layer ,它就像ps里的图层一样,可以对ps图层进行排序,上面的图层有更高的优先级,@layer 的一个重要作用,就是可以提前定义好“级联层”的优先级:
@layer one {
#button.super-specific-selector {
color: red;
}
}
@layer two {
button {
color: green;
}
}
正如你在上面看到的,我们只是使用@layer关键字来创建一个自定义层,给它任何我们想要的名称 。图层two的样式会覆盖图层one的样式。one无论其特殊性如何。
- 浏览器样式
- 用户风格
- 作者风格
- one
- two
如您所见,我们在作者样式中创建了两个新层,我们可以使用它们来组织我们的代码并使使用特定性更容易。
附加到图层如何将代码添加到现有层。
@layer one {
#button.super-specific-selector {
color: red;
}
}
@layer two {
button {
color: green;
}
}
@layer one {
.another-style {
color: blue;
}
}
在这个例子中你可以看到我已经定义one了两次图层。这完全没问题,实际上是在创建图层后向图层添加更多样式的方式。这样做不会影响层的顺序,因为层的顺序是由创建层的第一段代码决定的。这意味着我们one在 CSS 文件顶部的第一个图层实例将创建图层,因此本示例中的图层顺序与上一个示例中的相同。唯一的区别是我们能够在图层one创建后通过@layer再次使用关键字来添加额外的样式。等同如下
@layer one {
#button.super-specific-selector {
color: red;
}
.another-style {
color: blue;
}
}
@layer two {
button {
color: green;
}
}
定义层顺序
这种在创建图层后向图层添加样式的功能在定义图层顺序时非常有用。想象一下,您有以下几层
@layer base,application;
@layer application {
em {
color: red;
}
}
@layer base {
.item em {
color: green;
}
}
通过@layer base,application;按从左到右的顺序定义所有层,其中列出的base是最不具体的,最后指定的层application是最具体的。也是最先生效的。然后,您可以稍后使用正常@layer语法将代码添加到每个层,而不必担心定义层的顺序,因为它们都在这一行中定义。需要注意的是,这行代码必须在定义任何层之前出现,所以我通常将它作为我的 CSS 文件中的第一行。
导入图层很多时候,当你使用一个框架时,你可能会像这样将它导入到你的 CSS 中。
@import url("your.css");
如果要将所有这些导入的代码添加到特定层,只需添加layer(layer-name)到导入语句的末尾即可。
@import url("your.css") layer(layerName);
这会将所有样式添加your.css到layerName图层。但是,使用导入的一件事是它们的性能不是很好,因为首先您需要下载包含该@import语句的样式表,然后浏览器才能下载导入的文件。解决此问题的一种方法是在 HTML 中使用style标签。
<!-- link tag to stylesheet that define your layers -->
<link rel="stylesheet" href="styles.css">
<style>
@import url("your.css") layer(layerName);
</style>
通过像这样编写代码,您可以避免所有性能问题,@import但仍然可以获得直接导入图层的所有好处
匿名层匿名层指的是不声明layer名地级联层,它在级联层中的优先级,取决于layer声明次序:
@layer A {
body {
background-color: green;
}
}
@layer {
body {
background-color: red;
}
}
@layer B {
body {
background-color: bisque;
}
}
优先级从高到低为:B > 匿名 > A,所以最后生效的body背景色为bisque。这并不是我觉得太有用的东西,但如果你真的需要将少量的 CSS 代码分成一个层,这可能会很有用。
嵌套层我认为不太有用的另一个功能是能够将图层相互嵌套
@layer outer {
@layer inner {
.button {
color: red;
}
}
}
@layer outer.inner {
.another {
color: green;
}
}
通过使用上面的.语法或嵌套语法,您可以在其他层内创建层。这是您可能不会经常使用的东西,因为大多数应用程序只有几层,但如果您有一个非常复杂或大型样式系统,这可能会很有用。
重要的层概念这涵盖了创建图层的基础知识,但是您需要了解一些关于图层的概念才能充分利用图层。
非分层样式更先生效到目前为止,我们只处理了所有样式都在图层中的 CSS。当您的样式没有图层时,事情会变得有点复杂。
body {
background-color: blue;
}
@layer A {
body {
background-color: red;
color: black;
}
}
@layer B {
body {
color: blue;
background-color: green;
}
}
在这个例子中,我们有两个个A和B图层,然后是一个没有图层的样式。当您的代码不在任何层中时,它总是被认为比分层代码更具体。这意味着我们的有一个蓝色的背景。为了使这一点更容易理解,我喜欢将不在任何层中的代码视为在所有其他层之后定义的自己的层中。
- 浏览器样式
- 用户风格
- 作者风格
- A layer
- B layer
- 非分层样式
这有助于我可视化我的代码,因此我可以理解为什么非分层代码总是覆盖层内的代码。
!improtant该!important关键字使使用特异性变得困难,并且对于图层来说也没有什么不同。该!important关键字的工作方式与普通图层完全相反。如果您使用!important关键字定义样式,它将覆盖该层之后定义的层中的任何样式。
@layer one {
button {
color: red !important;
}
}
@layer two {
button {
color: green;
}
}
在上面的例子中,按钮文本将是红色的,因为我们之前!important定义了颜色。但是,如果我们尝试添加!important到 layertwo以覆盖!important来自图层one,它实际上不会更改按钮颜色。
@layer one {
button {
color: red !important;
}
}
@layer two {
button {
color: green !important;
}
}
这样做的原因是因为它!important的工作方式与普通图层相反。由于 layerone是在 layer 之前定义的,所以 layer中的two所有!important样式one都会覆盖 layer 中的任何样式,包括!important样式two。这意味着我们的按钮仍然是红色的。
如果我再加一个没有图层!important的普通样式,按钮又是什么颜色的呢?
@layer one {
button {
color: red !important;
}
}
@layer two {
button {
color: green !important;
}
}
button{
color: blue !important;
}
根据非分层样式更先生效,那自然按钮会是蓝色的。
浏览器支持对于每一个很酷的 CSS 功能,你总是需要考虑浏览器的支持,但幸运的是,对我们来说,图层得到了很好的支持,并且很快就会得到完美的支持。目前,layer有84.31% 的支持率,但这主要是因为这个功能最近才在最新版本的浏览器中推出。大多数现代浏览器在撰写本文时不到一个月前就推出了此功能,这意味着我们目前只是在等待用户将他们的浏览器更新到最新版本以支持此功能。
结论总之,@layer 还是蛮好用的,希望能尽快在业务代码里面用到吧。