2.2.1 @layer规则解决的问题
先讲解一下设计@layer
的初衷。
我们在实际开发的时候,经常会使用第三方组件。每个产品通常都有自己的UI样式风格,当引入第三方组件的时候,往往需要对这些组件的UI进行重置,例如换肤、变色等。此时,我们的做法是使用优先级更高的选择器进行覆盖,例如第三方组件中某个按钮的选择器是:
.container .some-button { height: 30px; }
当需要重置的时候,可能就会使用类似于下面的选择器,通过增加选择器复杂度的方式进行重置。
.reset .container .some-button { height: 40px; }
这就会使我们的CSS代码变得很臃肿,维护成本上升,同时过于复杂的选择器也使CSS渲染的性能不是很好。
又如这个困扰我很久的例子,对于链接元素的CSS reset
,有一种非常好的方法是使用:any-link
伪类,代码示意如下:
:any-link { color: darkblue; }
:any-link:hover { color: blue; }
其语义明确,匹配精准,且无须担心:visited
伪类的干扰,可以参见10.2节讲解的超链接伪类。
然而,这个伪类却很少有人使用,其原因只有一个,那就是伪类的优先级比较高,不太适合作为CSS reset
使用,因为一旦设置这个伪类,某个<a>
元素按钮想要被重置颜色,所需的选择器成本就会很高,提升了整个项目的选择器复杂度。
而有了@layer
规则,上面这些问题就迎刃而解了。我们只要将希望获得低优先级的CSS代码放在@layer
规则中,就无须再担心选择器优先级过高的问题,因为@layer
规则的级联层级比常规的CSS代码的级联层级低。
参见这里的CSS代码示意:
@layer {
.container .some-button { height: 30px; }
:any-link { color: darkblue; }
:any-link:hover { color: blue; }
}
/* 业务代码 */
.some-button { height: 40px; }
a { color: deepskyblue; }
此时相关的CSS代码在浏览器的优先级层级关系如图2-5和图2-6所示。
图2-5 按钮的单类名优先级更高
图2-6 <a>
元素优先级高于:any-link
伪类
从图2-5可以看出,虽然业务代码中的按钮选择器只有一个类名.some-button
,其优先级低于.container
和.some-button
这两个类名,但是由于代码所在的级联层级更高,因此,还是重置了30px
。
从图2-6可以看出,链接的颜色最终按照a
标签选择器渲染了,再也不用担心:any-link
伪类作为CSS reset
代码会影响业务代码中<a>
元素的样式设置了。
眼见为实,读者可以输入https://demo.cssworld.cn/selector2/2/2-1.php或者扫描下面的二维码查看对应的效果。
这就是@layer
规则的作用,可以让CSS代码的级联层级降低,从而确保主业务的CSS代码不受第三方组件的CSS代码的影响。