一、概述
多个样式表的声明顺序(声明优先级)和其选择器的权重(样式优先级)决定了元素使用哪个样式,其中没有被设置样式属性值的元素,通过继承或者使用属性初始值的方式赋值,从而决定了每个元素的最终样式展示。
Cascade layers(级联层):可以更明确地控制css的样式优先级,以防止样式冲突。
css声明的顺序
CSS Cascading and Inheritance Level 4 中指定有以下6种css声明的源, 相互冲突的声明将按以下顺序应用,后一种声明将覆盖前一种声明:
1用户代理样式表中的声明(例如,浏览器的默认样式,在没有设置其他样式时使用)。
2用户样式表中的常规声明(由用户设置的自定义样式)。
3作者样式表中的常规声明(这些是我们 web 开发人员设置的样式)。
4作者样式表中的 !important 声明
5用户样式表中的 !important 声明
6用户代理样式表中的 !important 声明
【注:标记为 !important 的样式的优先级顺序是颠倒的。】
按照上述算法,可以得到一个样式优先级递增的排序:
而有了 CSS @layer 之后,这个层叠优先级顺序有了更新,具体优先级如下:
从中我们可以看出,级联层@layer其实是新增的一种特性,和css声明来源结合起来生成新的来源,使其拥有不同的层叠优先级,参与层叠计算。
常规代码覆盖:缺点:太长了
.outer p {color: gray}
body .outer p {color:red}
a标签样式的重置:缺点:any-link优先级太高
:any-link { color: green; }
:any-link:hover { color: red; }
@layer
解决了:同一个 CSS 上下文中,有些 CSS 声明需要设置低优先级,且这种优先级不受选择器权重的影响。
二、语法
@layer {rules};
@layer layer-name {rules};
@layer layer-name;
@layer layer-name, layer-name, layer-name;
1. 基本语法
@layer {
.container .some-button { height: 30px; }
:any-link { color: blue; }
:any-link:hover { color: darkblue; }
}
2. 语法之名称加规则
@layer 还支持指定级联层的名称,适合用在需要多个级联分层的场景,方便维护与管理。
@layer button {
.container .some-button {
height: 30px;
}
}
@layer link {
:any-link {
color: blue;
}
:any-link:hover {
color: darkblue;
}
}
3. 语法之单名称
那 @layer layer-name 这个语法有什么用呢?
主要是用来灵活设置 @layer 规则和其他 @layer 规则的前后优先级。
例如,有一个级联层,名为 peacock, 希望这个级联层级别最低,但是,相关的 CSS 代码位置却无法控制,有可能在天边,也可能在眼前,此时,@layer layer-name这个语法就可以大放光彩了。
/* layer的调用*/
@layer rabbit;
……CSS……
……CSS……
……CSS……
/*layer的定义,虽然我在后方,但我优先级最前 */
@layer rabbit {
.blttom-layer {
content: 'yaojinbo'
}
}
三、让整个css变成@layer
1. import引用
匿名引入
@import './zrr.lib.css' layer;
定义名称,以便定义优先级
@import './zrr.lib.css' layer(lib);
设置优先级
layer local, lib;
@import './zrr.lib.css' layer(lib);
@layer local {
}
2. <link>引用
<!-- zxx-lib.css的样式属于名为 lib 的级联层 -->
<link rel="stylesheet" href="zrr-lib.css" layer="lib">
<!-- 样式引入到一个匿名级联层中 -->
<link rel="stylesheet" href="zrr-lib.css" layer>
四、嵌套
每多一层 @layer,则样式的优先级就下降一层。
@layer outer {
/* 上面优先级更高 */
button {
width: 100px;
height: 30px;
}
@layer inner {
button {
height: 40px;
width: 160px;
}
}
}
点.级联写法
@layer outer {
button {
width: 100px;
height: 30px;
}
}
@layer outer.inner {
button {
height: 40px;
width: 160px;
}
}
多嵌套
@layer A {
p { color: red; }
@layer B {
p { color: green; }
}
}
@layer C {
p { color: orange; }
@layer D {
p { color: blue; }
}
}
其中的优先级大小是这样的:C > C.D > A > A.B
五、!important对 @layer 的影响
!important对 @layer 的影响
如果你觉得以上都很简单,很不错,说明你已经掌握了它的规则,那咱们再一起来看看当!important和@layer级联层结合到一起会产生什么样的火花。
@layer A {
div {
background-color: red;
}
@layer B {
div {
background-color: green;
}
}
}
@layer C {
div {
background-color: blue;
}
@layer D {
div {
background-color: purple!important;
}
}
}
我们给@layer D层增加了!important标志,让我们猜一下结果会是怎样?按!important样式大于非!important样式的规则,应该最高优先级变成了D吧?不错,结果的确是@layer D的优先级变成最高,所以背景色是紫色。
如果,同时存在多个!important标志呢?
@layer A {
div {
background-color: red;
}
@layer B {
div {
background-color: green!important;
}
}
}
@layer C {
div {
background-color: blue;
}
@layer D {
div {
background-color: purple!important;
}
}
}
在上个例子的基础上,给B层中的样式也增加!important标志,这次应该谁获胜呢?按照前面的知识点,如果不加!important 标志的话,优先级 @layer C.D > @layer A.B,两者同时加上!important 标志,我猜应该还是 @layer C.D > @layer A.B,即显示为紫色,但是,经过实验发现,最终显示的颜色是绿色,正好和猜想的相反。
这里有另一个重要结论:
1!important样式始终高于非 !important 样式
2对于非!important样式时,级联排序越靠后(越小)的@layer 规则,优先级越低;!important样式时正好相反。
六、使用场景
1. 模式定制:飘红、飘黑等不同颜色选择
2.大型网站:内容较多、较乱
3. common样式:不用担心写法造成的样式混乱
4. 第三方插件样式:入侵性更小、样式覆盖更优雅
七、浏览器兼容性
目前没有针对layer的loader,可以在开发或者后台项目上小范围使用
若有收获,就点个赞吧