前端杂谈: CSS 权重 (Specificity)

字母哥的博客 2018-11-22 13:20:39 ⋅ 888 阅读

前端杂谈: CSS 权重 (Specificity)

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

  • 较长的 css selector 权重会大于较短的 css selector

  • id selector 权重高于 class selector.

但是具体规范是什么? 浏览器是按照什么标准来判定不同选择器的权重的呢?

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

第一个关键词: 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 和其元素的相关性. 相关性越强, 即表示表示其权重最高.

那么问题来了, 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 的数目决定的.

第二个关键词: Selector Type

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

  • a: 如果 css 属性声明是写在 style=“” 中的, 则数目为 1, 否则为 0

  • b: id 选择器的数目

  • c: class 选择器, 属性选择器(如 type=“text”), 伪类选择器(如: ::hover) 的数目

  • d: 标签名(如: pdiv), 伪类 (如: :before)的数目

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

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

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

还有一些 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 节点背景色应该是黑色. 让我们看看结果:

结果我们得到的是一个红色的 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 选择器包含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;
}

让我们看看结果:

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

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

---------------END----------------

后续的内容同样精彩

长按关注“IT实战联盟”哦



全部评论: 0

    我有话说:

    推荐一款前端数据源管理工具 algeb

    ALGEB 简介 这是一个比较抽象的库,一开始可能比较难理解。我写它的初衷,是创建可响应的数据请求管理。在传统数据请求中,我们只是把携带ajax代码的一堆函数放在一起,这样就可以调用接口。但是这种方案不是很灵活,无法解决共享数据源,数据没回来时怎...

    WebStorm 2020.3 发布,支持 Tailwind CSS,Git Staging 等

    WebStorm 2020.3 发布,这是本年度最后一次重大更新。重要更新包括对 Tailwind CSS 的支持,将 IDE 主题与操作系统设置同步,以及 Git Staging。 外观

    Node&RabbitMQ系列三

    ,如:连、限流。 本文目标: 单独抽离rabb...

    字节跳动 | 微服务架构中如何优雅地试?

    背景 在微服务架构中,一个大系统被拆分成多个小服务,小服务之间大量 RPC 调用,经常可能因为网络抖动等原因导致 RPC 调用失败,这时候使用试机制可以提高请求的最终成功率,减少故障影响,让系统

    Nacos 1.4.1 发布,修复指定特殊 UA 可绕过所有鉴的安全漏洞

    Nacos 1.4.1 已发布,此版本的主要新功能是支持 IPv6 服务注册,以及为 Csharp 客户端提供 UDP push 支持。 更值得关注的是,1.4.1 版本解决了此前被曝出的绕过鉴

    接上篇:前端必看的8个HTML+CSS技巧(下)

    4款非常容易上手的酷炫效果,值得收藏。

    【总结】前端5大常见设计模式,代码一看你就懂!

    用代码示例来掌握前端5大设计模式

    仿今日头条 Gfast CMS 前端发布

    Gfast 开源以来,CMS管理模块一直深受大家喜欢于是就有朋友建议弄一个CMS前端给大家学习使用,然而由于公司最近事项比较多,所以一直没能及时处理,今天终于把所有的前端处理完成,大家可以去下载学习

    移动H5前端五大性能优化方案(实战篇)

    移动H5前端五大性能优化方案(实战篇)

    Web前端:单页应用部署时缓存策略

    前端网站采用Vue + Nginx的方式进行生产环境部署。发现登录系统之后,出现页面空白问题,刷新几次后显示正常。

    前端框架 Angular 11.0.0 正式发布,不再支持 IE 9 、10

    前端框架 Angular 11.0.0 正式发布。 Angular 11.0.0 将 TypeScript 升级到 4.0, 对 TypeScript 3.9 不再支持。 放弃了对 IE 9 、10

    Angular 11.1.0 正式发布,支持 TypeScript 4.1

    Angular 是一个基于 TypeScript 的开源前端框架,由 Google 的 Angular 团队以及社区共同领导。Angular 是由 AngularJS 的同一个开发团队完全写而成的

    Fes.js v0.4.1 版本发布,一套优秀的中后台系统前端解决方案

    Fes.js 是一套优秀的中后台前端解决方案。提供初始项目、开发调试、Mock接口、编译打包的命令行工具。内置布局、权限、数据字典、状态管理、存储、Api等多个模块。以约定、配置化、组件化的设计思想

    xrkmonitor 字符云监控系统 v3.3 日志系统增强

    该版本主要增强日志系统功能,包括引入通用日志文件监控插件,核心代码上日志系统新增日志数和日志类型统计图表,日志系统按配置大小自动滚动日志;插件架构上,插件配置项通过引用排序可实现排序显示,插件的

    MoguBlog(蘑菇博客)v5.3发布,前后端分离博客系统

    MoguBlog简介 MoguBlog(蘑菇博客),一个基于微服务架构的前后端分离博客系统。前台使用Vue + Element , 后端使用spring boot + spring cloud

    Redis系列二:位图实战,实现打卡签到

    前言 如果要统计一篇文章的阅读量,可以直接使用 Redis 的 incr 指令来完成。 如果要求阅读量必须按用户去,那就可以使用 set 来记录阅读了这篇文章的所有用户 id,获取