在这篇博客里,我想跟大家聊聊关于css选择器优先级的话题。虽然是个”老话题”,但是在最近的研究中我发现了一些新东西,本着 好记性不如烂笔头 的原则,决定整理成文分享出来,希望对正在阅读本文的你有所帮助,废话不多说,开始吧
详解css选择器的优先级
当多个css选择器作用于同一个元素的同一个属性时,浏览器会通过优先级来判断哪一个选择器是最终会被应用的,从而在该元素上展示对应选择器下所定义的样式
选择器优先级的权重是由 其中每一个子选择器所对应的权重值之和 来决定,其中每一个子选择器所对应的权重值如下
- 如果声明在 style 里的属性(内联样式),则权重值 +1000
- 选择器中包含 ID选择器,则权重值 +100
- 选择器中包含 类选择器、属性选择器、伪类选择器, 则权重值 +10
- 选择器中包含 元素选择器、伪元素选择器, 则权重值 +1
需要注意: 通配选择符(*)和关系选择符(+, >, ~)不参与权重值的计算
如果两个权重相同的选择器作用于同一处,那么后面的那个选择器会被最终应用到元素上,这就是所谓的“后来居上”
接下来再聊聊无视上述规则的家伙: !important
一手遮天的家伙 👉 !important
important 它就很🐮了,它可以覆盖任何其他声明,虽然从技术上讲, !important 与优先级无关,但它与最终的结果直接相关,所以可以认为它的权重值为10000(反正比内联的高🤪),当两个作用于同一个元素的同一个属性的选择器都带有 !important 时,拥有更大权重的选择器将会被采用(也就是忽略掉 !important 后,剩下的选择器的权重值之和)
正是因为它太强大了,所以我们使用它时一定要特别小心,总结了一些经验,下面分享给你
- 一定要优先考虑使用样式规则的优先级来解决问题而不是 !important
- 只有在需要覆盖全站或外部 CSS 的特定页面中使用 !important
- 永远不要在你的插件中使用 !important
- 永远不要在全站范围的 CSS 代码中使用 !important
上面讲解的东西你也许早就门儿清了,那么接下来就聊一些你也许不知道的东西吧😏
详解【层叠】
上文讲述的优先级其实都只是在 页面作者定义的样式 这个维度去判断的,但是css是存在 层叠 这个概念的,也就是说存在很多维度,所以上文的判断方式是存在问题的,那什么是正确的方式呢?请接着往下看😉
层叠是CSS的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法,它在CSS处于核心地位,CSS的全称层叠样式表正是强调调了这一点。在css里存在的样式源有5个,它们分别是:
- 浏览器会有一个基本的样式表来给任何网页设置默认样式。这些样式统称用户代理样式
- 网页的作者可以定义文档的样式,这是最常见的样式表。大多数情况下此类型样式表会定义多个,它们构成网站的视觉和体验,即页面主题,可以理解为页面作者样式
- 作为浏览器的用户,可以使用自定义样式表定制使用体验,可以理解为用户样式
- 动画(Animation),指使用 @Keyframes 规则定义状态间的动画,动画序列中定义关键帧的样式来控制CSS动画序列
- 过渡 (Transition)
这些所有来源里的样式会被归类到不同的层叠维度中,根据 CSS Cascading 4 的最新标准,当前层叠顺序优先级如下(越往下的优先级越高):
- Normal user agent declarations
- Normal user declarations
- Normal author declarations
- Animation declarations
- Important author declarations
- Important user declarations
- Important user agent declarations
- Transition declarations
翻译一下
这只是一个标准规范,因为每家浏览器厂商都会有各自的实现,所以在不同浏览器甚至同一浏览器的不同版本上都会有一定差别,因此需要自己实际去摸索才行,所谓 实践才是检验真理的唯一标准
通过这一节的讲解,我们知道了对于在第一节中所讨论的选择器优先级的问题,其实都是以所有样式都是 页面作者样式 的前提来探讨的,显然这是有问题的,因此如果要判断某一个元素最终展示的样式,除了需要比较样式优先级之外,还需要比较样式所在的层叠维度的优先级,并且层叠顺序应该是优先考虑的(只有在层叠维度优先级相等时,才再去判断选择器的优先级)
总结
其实有时候去重新挖掘一些”老东西”还是蛮有趣的,一是可以巩固已知的知识,二是可以幸运地发现一些新的东西,从而拓展自己的知识面,我想这就是人们常说的 温故而知新 吧🤪