html 样式权重,CSS 权重详解

对于 CSSer 来说,多多少少都会遇到过 “样式规则不生效?”、“样式规则被覆盖?” 等等问题,这些都与 CSS 权重有关系。

选择器匹配原理

在此之前,容我先简单介绍浏览器是怎么通过各种选择器,把样式规则和 DOM 元素扯上关系的。

浏览器中存在着专门的渲染引擎来渲染 HTML 文档。这里以 Webkit 内核为例,在启动渲染流程时,引擎一方面会解析 HTML 文档,构建 DOM 节点树(DOM Tree),另一方面会解析样式文件生成 样式规则(Style Rules),然后结合分析 DOM 树和样式规则生成 渲染树(Render Tree),最后 布局 和 绘制 出 UI 界面。

2fcd2be97202?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Webkit 渲染流程(摘自 https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/)

CSS 的选择器匹配就发生在 渲染树 的构建过程。浏览器会从 DOM 树的根节点开始遍历每个可见节点,对于每个可见节点都会在规则表中查找适配的样式规则。那么,如此庞大的样式数据和复杂的选择器结构,渲染引擎是怎么寻找到适配当前元素的样式规则呢?

请看下面这个复合选择器。如果引擎是按照从左向右的顺序匹配选择器,将会导致大量 回溯 的发生:先是在当前节点到 DOM 树跟节点的路径上寻找 div 元素,然后沿着分支路径继续往下找第二个 div 元素,如果当前路径找不到,就得回退到上一个 div 元素尝试另一条分支路径。如此往复,对性能损耗将会非常严重。

div div span .text {}

所以,引擎是采取 从右向左 的顺序来匹配选择器。也就是 从最具体的选择器开始,如果与当前节点不匹配,则直接抛弃该条规则;如果匹配,只需要沿着路径往上确认其他选择器是否也匹配,这样做可以大大减少无效的匹配数,提高性能。除此之外,引擎还会把不同类型的选择器(id、class、tag 及其他类型)归类到哈希表中,进一步减少查找基数。

了解选择器的匹配原理,有利于我们理解其权重规则,对于编写简洁、高效的 CSS 代码非常有帮助。

CSS 权重

通过不同的方式(内联样式、外部样式表)、不同类型的选择器组合针对某个元素声明样式规则时,如何决定最终哪个声明会被应用到元素上?这就涉及到 CSS 权重(也指优先级,Specificity)。

围绕 CSS 权重主要有以下三条规则:

权重不同的样式规则作用于同一元素时,权重高的规则生效;

权重相同的样式规则作用于同一元素时,后声明的规则生效;

选择器在 DOM 中的位置关系不会对规则产生影响。

body div {

color: red;

}

html div {

color: blue;

}

测试

2fcd2be97202?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

这里的 body 标签元素在 DOM 中离目标 div 更近,但最后还是按照样式规则的声明顺序来决定。

直接作用于元素的样式规则优先级高于从祖先元素继承的规则;

#parent {

color: red;

}

span {

color: blue;

}

测试

2fcd2be97202?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

CSS 权重等级

如何比较不同选择器的权重高低?这里划分成 5 个权重等级,按照等级 由高到低 的顺序:

!important 关键字

内联样式

测试

id 选择器

#demo {}

类选择器、属性选择器、伪类选择器

.demo {}

[type="text"] {}

div:hover {}

div:first-child {}

需要注意,否定伪类(:not())比较特殊,它不会对权重产生影响,但是 否定伪类内部的选择器会影响权重。

div#demo span {

color: red;

}

div:not(#demo) span {

color: blue;

}

普通 demo

否定伪类 demo

2fcd2be97202?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

实例中,:not(#demo) 的权重值和 #demo 的权重值是相等的,所以后面声明的样式规则成功生效。

标签选择器、伪元素选择器

div {}

div:before {}

div:after {}

除了上述的选择器之外,通配符选择器(*) 和 结合符(+、>、~)对优先级没有影响。

对于复杂的复合选择器,我们需要逐个等级比较权重大小,不允许跨越等级比较。为了方便计算,我们可以把权重值具象化,每出现一个选择器就在其对应的等级区间中权重值加 1,参考下面实例:

* {} /* 权重值 0-0-0-0-0 */

div {} /* 权重值 0-0-0-0-1 */

div h1+h2 {} /* 权重值 0-0-0-0-3 */

div, ... div {} /* 权重值 0-0-0-0-n */

#demo a:hover {} /* 权重值 0-0-1-1-1 */

国外大神 把 CSS 权重的计算模拟成海洋生物链,选择器组合权重越大则在生物链位置越高,非常浅显生动,建议收藏。

2fcd2be97202?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

图片转自 https://specifishity.com/

建议

在充分了解 CSS 选择器匹配原理和权重规则之后,在编写 CSS 代码时不妨多注意以下细节:

尽量不要使用 !important,尤其是在 对外提供的插件 和 全站范围的样式表 中,这会对模块代码中的样式覆盖带来非常大的麻烦。

!important 关键字的权重值为 1-0-0-0-0,只需要按照权重规则继续累加权重值即可覆盖该样式属性。

div {

color: red !important;

}

/* 通过 id选择器 增加权重 */

#demo {

color: blue !important;

}

测试

减少不必要的选择器嵌套,嵌套最好不要超过三级。大量的复合选择器,会影响选择器匹配的效率,同时也会增加 CSS 样式文件的体积,不易维护。

当出现大量嵌套时,我们可以指定一个更具体的类选择器来替换复合选择器。

body div ul li span {}

.li {}

Reference

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSS选择器的权重计算是通过CSS Specificity(特殊性)来确定的。在计算权重时,可以按照以下规则进行计算: 1. 选择器的特殊性由选择器本身的组成部分决定,包括元素选择器、类选择器、id选择器和内联样式。通常来说,id选择器的特殊性最高,其次是类选择器和属性选择器,再次是元素选择器。 2. 对于相同特殊性的选择器,后面出现的选择器会覆盖前面出现的选择器。 3. 使用!important声明的样式具有最高的特殊性,将覆盖其他所有的样式。 根据上述规则,可以用以下公式来计算选择器的权重: - id选择器:权重为1,例如#myId{} - 类选择器、属性选择器或伪类选择器:权重为10,例如.class{}、[type="text"]{}、:hover{} - 元素选择器或伪元素选择器:权重为100,例如div{}、::before{} - 内联样式权重为1000,例如<div style="color:red;"> 在计算完各个选择器的权重后,具体的权重比较规则是:按照权重从左到右依次比较,权重值较大的样式会覆盖权重值较小的样式。 需要注意的是,CSS权重计算只适用于冲突的样式规则。如果没有发生冲突,那么所有样式规则都会生效。 总结起来,CSS选择器的权重计算是通过特殊性来确定的,特殊性由选择器本身的组成部分决定,而权重比较是按照权重从左到右依次比较的原则。这样,在编写CSS样式时,我们可以更好地控制样式的优先级。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CSS选择器与权重计算(详细)](https://blog.csdn.net/weixin_44164982/article/details/107227294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [CSS选择器的权重计算](https://blog.csdn.net/u010297791/article/details/58602255)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值