温故知新
针对 CSS 优先级,我们的认知可能是这样:内联、CSS各种选择器、!important,
你是否遇到过优先级覆盖成本太高、优先级无法覆盖等情况?本文将带你重新认识 CSS 优先级。
css 优先级分为两大类:继承和级联
继承指的是类似 color, font-family, visibility 等属性父元素设置,子元素会被继承的特性。
inherit 关键字可以让元素继承父元素的属性,可以用来覆盖原来的值
继承优先级最低;层级越深优先级越高
思考:文字最终的颜色?
css 一层层的优先级规则可看作级联(分层+嵌套关系称为级联)
Transition 过渡声明
设置了 !important 的浏览器内置样式
设置了 !important 的用户设置样式
@layer 规则中的 !important 样式
开发者设置的 !important 的 样式
animation 动画
开发设置的 css
@layer 规则样式
用户设置的样式
浏览器内置样式
user agent stylesheet:用户代理样式,就是浏览器内置的样式
@layer 声明了一种级联层级,使得开发者可以控制更多层级规则
其兼容性如下:
我们在实际开发的时候,经常会使用第三方组件。但是这些组件虽然功能是我们需要的,但是 UI 样式却和产品的风格不一致,我们需要对这些组件的 UI 进行重置,换肤,变色什么的。有些 Web 组件甚至还有 CSS reset 代码,而所有的 CSS 在同一个文档流中都公用同一个上下文(无论是 Shadow DOM 还是 iframe 都可以看成是一个独立的上下文),这就导致这些 CSS 代码会影响全局样式。
@layer 诞生之前,常见 CSS 优先级覆盖场景存在各种问题:
<div class="container">
<div class="some-button">button</div>
</div>
.some-button {
color: 'red'
}
覆盖后可能是下面这样的,如果场景多了会导致代码变得很臃肿,复杂选择器 会让 css 渲染性能变差:
.container .some-button {
color: 'green'
}
例如 any-link 语义好,匹配最精准,且无需担心 :visited
伪类的干扰,但优先级较高
<a href="xxxx">link</a>
图中我们可以看到 any-link 的优先级最高
基于以上场景,@layer 提供了一种更为优雅的方案来 管理 CSS ,下面介绍其使用方法
@layer layer-name {rules};
@layer layer-name;
主要是用来灵活设置 @layer 规则和其他 @layer 规则的前后优先级。
@layer layer-name, layer-name, layer-name;
在默认情况下,@layer 规则内 CSS 声明的优先级是按照前后顺序来的
@layer {rules};
优先级低于常规 CSS,详见 层级规范
我们依然举前面的例子,使用 @layer 前 vs 使用 @layer 后,显然 @layer 的管理更灵活,更清晰:
使用 @layer 前
使用 @layer 后
优先级:常规 CSS > @layer
嵌套越内部优先级越低
内外嵌套语法还可以写成下面这样:
@layer btn2 {
button {
}
}
@layer btn2.inner {
}
多嵌套语法下的优先级
内部的 @layer 的优先级由外部的 @layer 规则决定。
下图中优先级:btn2
> inner2
> btn1
> inner1
通过以下方式可以让整个 CSS 文件样式优先级降低
@import './test.css' layer(some-name);
<link rel="stylesheet" href="test.css" layer="some-name">
@layer
的诞生,让我们能更好的管理 CSS 样式/CSS 文件 的优先级,可以最大程度避免选择器、!important
的滥用、属于比较重大的一次革新
上图中已经看到层级规则中带 !important 的存在其规律:
如果想开发时直接覆盖浏览器内置 !important 或者插件注入样式的 !important,那就放弃吧 😜,层级规则就是如此!
优先考虑使用样式规则的优先级来解决问题而不是 !important
只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important
不要在你的插件中使用 !important
不要在全站范围的 CSS 代码中使用 !important
内联 > ID > 类、伪类、属性选择器 > 标签 > 通配符 、功能伪类(不带参数,where 除外)
https://segmentfault.com/a/1190000017970486
css reset,举例:a { color: blue; }
Shadow DOM 可以理解为 DOM 中的DOM,创建Shadow DOM是为了允许在Web平台上本地封装和组件化,而不必依赖像
:not()、:is()、:where(any-selector)
:not()
伪类的本身没有优先级,最终优先级是由括号里面的选择器决定的。
我们来自字节跳动,是旗下西瓜视频前端部门,负责西瓜视频的产品研发工作。
我们致力于分享产品内的业务实践,为业界提供经验价值。包括但不限于营销搭建、互动玩法、工程能力、稳定性、Nodejs、中后台等方向。
欢迎关注我们的公众号:xiguafe,阅读更多精品文章。
我们在招的岗位:https://job.toutiao.com/s/B6adncN。招聘的城市:北京/上海/厦门。
欢迎大家加入我们,一起做有挑战的事情!
谢谢你的阅读,希望能对你有所帮助,欢迎关注、点赞~