前端杂谈: CSS 权重 (Specificity)

前端杂谈: CSS 权重 (Specificity)

css 权重想必你们都据说过, 一些简单的规则大部分人也都知道:css

  • 较长的 css selector 权重会大于较短的 css selector
  • id selector 权重高于 class selector.

可是具体规范是什么? 浏览器是按照什么标准来断定不一样选择器的权重的呢?html

让咱们来看一下官方文档是怎么说的~前端

第一个关键词: Specificity

Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied. Specificity is based on the matching rules which are composed of different sorts of CSS selectors

官方文档中用 Specificity: 特异性 来表示一个 css selector 和其元素的相关性. 相关性越强, 即表示表示其权重最高.git

那么问题来了, Specificity 是如何被比较的呢?

Specificity is a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector.

Specificity 是由 selector 中 不一样 selector type 的数目决定的.github

第二个关键词: Selector Type

根据 W3 标准中的规定, css selector 分为 4 种 type: a, b, c, d. 他们的数目计算规则为:浏览器

  • a: 若是 css 属性声明是写在 style=“” 中的, 则数目为 1, 不然为 0
  • b: id 选择器的数目
  • c: class 选择器, 属性选择器(如 type=“text”), 伪类选择器(如: ::hover) 的数目
  • d: 标签名(如: p, div), 伪类 (如: :before)的数目

在比较不一样 css selector 的权重时, 按照 a => b => c => d 的顺序进行比较.app

由第一个 selector type a 的计算规则可知: 写在 html 代码 style 属性中的 css 相较写在 css 选择器中的 css 属性具备最高的优先级.ide

而 id selector (b) 相较 class selector (c) 有更高的优先级. 这也和咱们平时的经验相吻合.post

还有一些 css 选择器你没提, 它们该怎么计算权重?

除了上面 Specificity 计算规则中的 css 选择器类型, 还有一些选择器如: *, +, >,:not() 等. 这些选择器该如何计算其权重呢?测试

答案是这些选择器并不会被计算到 css 的权重当中 :)

有一个须要特别注意一下的选择器: :not(), 虽然它自己是不计权重的, 可是写在它里面的 css selector 是须要计算权重的.

若是 a,b,c,d 算完都同样, 怎么办?

默认行为是: 当 specificity 同样时, 最后声明的 css selector 会生效.

若是我重复一样的 css selectory type, 权重会增长吗?

让咱们来作个实验, 咱们声明一个 html 节点:

<div>
  <div id="testId" class="testClass"><span>test div</span></div>
</div>

在 css 中咱们添加两个选择器:

.testClass.testClass {
  background-color: red;
}
.testClass {
  background-color: black;
}

若是重复的 css selector 会被忽略的话, 按照前面的规则, 最后声明的 css selector 会生效, 因此 这个 div 节点背景色应该是黑色. 让咱们看看结果:

FSvsHI.png

结果咱们获得的是一个红色的 div, 也就是说 .testClass.testClass 高于 .testClass. 因此结论是: 重复的 css selector, 其权重会被重复计算.

关于 !important:

按照 MDN的说法, !important 是不在 css 选择器的权重计算范围内的, 而它之因此能让 css 选择器生效是由于浏览器在碰见 !important 时会进行特殊的判断. 当多个 !important 须要进行比较时, 才会计算其权重再进行比较.

一般来讲, 不提倡使用 !important. 若是你认为必定要使用, 不妨先自检一下:

  • 老是先考虑使用权重更高的 css 选择器, 而不是使用 !important
  • 只有当你的目的是覆盖来自第三方的 css(如: Bootstrap, normalize.css)时, 才在页面范围使用 !important
  • 永远不要 在你写一个第三方插件时使用 !important
  • 永远不要在全站范围使用 !important

一些误导的信息

我在搜索关于 css 权重的资料时, 看到了下面这张图, 看似十分有道理, 但实际上是错误的!css_weight1

让咱们来作一个简单的测试:

按照图片中的计算公式: 若是一个 css 选择器包含11 个 class selector type, 另外一个选择器是1 个 id selector type. 那么 class 选择器的权重会高于 id 选择器的权重. 让咱们来试一试:

.testClass.testClass.testClass.testClass.testClass.testClass
  .testClass.testClass.testClass.testClass.testClass {
  background-color: red;
}
#testId {
  background-color: black;
}

让咱们看看结果:

FSvfgg.png

结果显示仍是 id 选择器权重更高.

虽然咱们在实际编码过程当中不多会出现 10 多个 class 的状况, 但万一出现了, 知道权重真正的计算比较规则, 咱们才能正确的处理~

想了解更多 前端 和 数据可视化 ?

这里是个人 D3.js数据可视化 的 github 地址, 欢迎 star & fork

D3-blog

若是以为本文不错的话, 不妨点击下面的连接关注一下 : )

github 主页

知乎专栏

掘金

想直接联系我 ?

邮箱: ssthouse@163.com

相关文章
相关标签/搜索