超级面板
文章目录
最新文章
最近更新
文章分类
标签列表
文章归档

CSS 选择器优先级

在我们学习 css 的时候就了解样式优先级的排序是:!important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性,我们看一下它们到底具体是如何定义的。

css 的样式有三种来源,页面开发者,用户(使用浏览器的人设置的样式),和用户代理(浏览器),这些样式表会在一定的范围内重叠,互相影响页面的最终样式。

当然, css 的层叠规则也指定了不同样式的权重,当这几种规则同时存在的时候,优先级高的规则生效。

样式表层叠顺序

  1. 在应用样式之前,会根据媒体查询(@media 规则)过滤掉一部分样式。

  2. 需要说明的是,样式的声明包含普通声明和重要声明(就是样式末尾有 !important)。然后样式的优先级升序排序如下:

  3. 用户代理声明(浏览器默认,比如按钮的默认样式)

  4. 用户常规声明

  5. 开发者常规声明

  6. 开发者重要声明(!important

  7. 用户重要声明(!important

  8. 相同的优先级的样式规则按照选择器的特殊性排序,选择器权重高的将覆盖权重一般的,其中伪元素和伪类被分别算作常规元素和类,具体如何计算在下一节详细说明。

  9. 如果选择器的权重一致,则按照声明的顺序排序,后声明的样式覆盖先声明的样式。引入的样式表中的声明被认为在样式表本身的所有声明之前。

这种层叠顺序可以保证了浏览器赋予页面元素默认的初始属性(用户代理声明,优先级最低),同给予了开发者编写比用户和用户代理更高权重样式的能力(开发者声明,优先级高于用户代理和用户常规声明,去掉非用户重要声明的样式),之后又提供了用户强制去除开发者样式的能力(用户重要声明,表达用户强制修改的意愿)。

计算选择器的特殊性

选择器有多个类比,比如标签选择器、类选择器、ID选择器等,不同的选择器有不同的优先级,最终根据优先级计算出样式规则的权重,权重高的覆盖权重低的规则,权重计算如下:

  1. 如果声明来自内联规则(写在 html 标签的 style 属性内),则计 a=1,否则为 a=0
  2. 计算选择器中 ID 选择器的数量,赋值给 b
  3. 计算选择器中类选择器、属性选择器和伪类(如 :lang:active)的数量,赋值给 c
  4. 计算选择器中元素名(如 divp)和伪元素(如 :before:after)的数量,赋值给 d

最后,选择器的权重由 a-b-c-d 决定,a 的优先级最高,a 值相同则比较 b值,以此类推,类似于软件的版本号规则。

看几个示例,优先级从上往下增加:

*             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
li {} /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
li:first-line {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul li {} /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
ul ol+li {} /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
ul ol li.red {} /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
li.red.level {} /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
#x34y {} /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
style="" /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

注意,本节的优先级计算仅在第一节中的声明顺序一致的情况下才有意义,这也是为什么 !important 的优先级最高。

参考