整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

CSS 权重详解

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

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取

选择器匹配原理

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

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

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 中的位置关系不会对规则产生影响。
<html>
 <head>
 <style>
 body div {
 color: red;
 }
 html div {
 color: blue;
 }
 </style>
 </head>
 <body>
 <div>测试</div>
 </body>
<html>


  • 这里的 body 标签元素在 DOM 中离目标 div 更近,但最后还是按照样式规则的声明顺序来决定。
  • 直接作用于元素的样式规则优先级高于从祖先元素继承的规则;
<html>
 <head>
 <style>
 #parent {
 color: red;
 }
 span {
 color: blue;
 }
 </style>
 </head>
 <body>
 <div id="parent">
 <span>测试</span>
 </div>
 </body>
<html>


CSS 权重等级

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

  • !important 关键字
  • 内联样式
<div style="color: #fff;">测试</div>

id 选择器

#demo {}

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

.demo {}
[type="text"] {}
div:hover {}
div:first-child {}

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

<html>
 <head>
 <style>
 div#demo span {
 color: red;
 }
 div:not(#demo) span {
 color: blue;
 }
 </style>
 </head>
 <body>
 <div id="demo">
 <span>普通 demo</span>
 <div id="pseudo">
 <span>否定伪类 demo</span>
 </div>
 </div>
 </body>
<html>


  • 实例中,: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 权重的计算模拟成海洋生物链,选择器组合权重越大则在生物链位置越高,非常浅显生动,建议收藏。

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

建议

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

  • 尽量不要使用 !important,尤其是在 对外提供的插件全站范围的样式表 中,这会对模块代码中的样式覆盖带来非常大的麻烦。
  • !important 关键字的权重值为 1-0-0-0-0,只需要按照权重规则继续累加权重值即可覆盖该样式属性。
<html>
 <head>
 <style>
 div {
 color: red !important;
 }
 /* 通过 id选择器 增加权重 */
 #demo {
 color: blue !important;
 }
 </style>
 </head>
 <body>
 <div id="demo">测试</div>
 </body>
<html>

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

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

lt;img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110853564.jpg" data-caption="" data-size="normal" data-rawwidth="711" data-rawheight="230" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110855421.jpg" class="origin_image zh-lightbox-thumb" width="711" data-original="https://pic2.zhimg.com/v2-1a61d5196d8d77ff8fa263e9d34ee50d_r.jpg"/>

Unlike a programming language that requires knowledge of loops, variables, and other concepts, CSS is pretty easy to pick up. Maybe it’s because of this that it has gained the reputation of being simple. It is simple in the sense of “not complex”, but that doesn’t mean it’s easy.Mistaking “simple” for “easy” will only lead to heartache. -- by @Jeremy Keith

这就是为什么写得好CSS不多见。

而对于Web页面和Web应用而言,他的构层主要由HTML、CSS和JavaScript。其中HTML和CSS的关系又是紧密相连:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110856569.jpg" data-caption="" data-size="normal" data-rawwidth="1338" data-rawheight="982" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110857373.jpg" class="origin_image zh-lightbox-thumb" width="1338" data-original="https://pic1.zhimg.com/v2-623bc8f730ea257e7bb7ddd3a8f3e8f4_r.jpg"/>

简单地说:

  • HTML的DOM树会直接影响你CSS选择器的使用
  • HTML的元素命名也会直接影响你CSS选择器的使用

那么首要解决的问题就是写好HTML结构,写好HTML结构,写好HTML结构;定义好的类名,定义好的类名,定义好的类名。

怎么做到呢?徒手撸出类似Bootstrap的HTML:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110858742.jpg" data-caption="" data-size="normal" data-rawwidth="2156" data-rawheight="904" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110859214.jpg" class="origin_image zh-lightbox-thumb" width="2156" data-original="https://pic1.zhimg.com/v2-fbcef8c2ae794c77c64940d2c4c87450_r.jpg"/>

比如写个Button:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110900377.jpg" data-caption="" data-size="normal" data-rawwidth="1740" data-rawheight="692" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110902559.jpg" class="origin_image zh-lightbox-thumb" width="1740" data-original="https://pic3.zhimg.com/v2-4220af0fb4d6802bf93dc81aacfd9afd_r.jpg"/>

就我个人而言,HTML结构都喜欢写成Bootstrap这种。

Bootstrap​

getbootstrap.com

另外就是在写组件或者HTML结构时还可以参照 "Accessible Rich Internet Applications "规范中的Widget部分:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110903708.jpg" data-caption="" data-size="normal" data-rawwidth="1684" data-rawheight="1270" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110906468.jpg" class="origin_image zh-lightbox-thumb" width="1684" data-original="https://pic3.zhimg.com/v2-e06a5e8610c65467ece6594fc717d04a_r.jpg"/>

Accessible Rich Internet Applications (WAI-ARIA) 1.1​

www.w3.org

另外,还可以参考一些优秀的网站,Frameworks,库。这样可以提高自己在HTML方面的能力,比如结构的管理,类名命名。更多的话可以阅读一些关于HTML语义化的文章。

回到CSS上来。很多撸CSS的同学常常会犯的问题:

  • 选择器运用不好
  • 属性了解不够到位
  • 不够成体系
  • 实现思路不好
  • 眼界不广
  • 不知道借助工具
  • 等等

选择器运用不好

选择器的使用在CSS中绝对算是重中之重。CSS发展到目前为止,选择器已经非常的成熟了,可以实现很多类似于早期jQuery的选择器功能。

如果前期的HTML写的足够好,在选择器定位到目标元素时就会变得较为轻松,而且可读性也会较强。很同学用不好选择器,除了不知道怎么用之外,还有一个更重要的原因,选择器权重不理解。

所以说,要用好选择器,就需要知道 CSS选择器是怎么一回事,CSS选择器权重如何计算

有关于选择器相关的教程网上也很多,这里列几篇:

CSS3 选择器--基本选择器_css3选择器, 基本选择器, CSS选择器 教程_w3cplus​

www.w3cplus.com

CSS3 选择器--属性选择器_css3选择器, 属性选择器, CSS选择器 教程_w3cplus​

www.w3cplus.com

CSS3 选择器--伪类选择器_css3选择器, 伪类选择器, CSS选择器 教程_w3cplus​

www.w3cplus.com

CSS选择器的优化_基本选择器, CSS选择器 教程_w3cplus​

www.w3cplus.com

再聊CSS的属性选择器_CSS, CSS选择器 教程_w3cplus​

www.w3cplus.com

初探CSS 选择器Level 4​

www.w3cplus.com

你应该知道的一些事情--CSS权重_CSS选择器 教程_w3cplus​

www.w3cplus.com

使用CSS Mod Queries控制选择器范围​

www.w3cplus.com

属性了解不到位

CSS的属性事实上并不是非常的复杂,但他们的组合就会让很多人感到头痛了。如果希望不头痛就需要对CSS的属性有所了解。建议可以从相关规范中获取:

All Standards and Drafts​

www.w3.org

而CSS中较为重要的几个功能模块:

选择器模块:

Selectors Level 4​

www.w3.org

盒模型

CSS Box Model Module Level 3​

www.w3.org

特别是逻辑盒模型的出现,将会让很多CSSer更为头痛,拿下图来对比一下:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110908744.jpg" data-caption="" data-size="normal" data-rawwidth="4096" data-rawheight="1476" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110909991.jpg" class="origin_image zh-lightbox-thumb" width="4096" data-original="https://pic1.zhimg.com/v2-b8c079e508817f0d8ec4b7021a0e936d_r.jpg"/>

CSS的逻辑属性对盒模型带来的变化_CSS, CSS逻辑属性 教程_w3cplus​

www.w3cplus.com

布局模块:

CSS Flexible Box Layout Module Level 1​

www.w3.org

CSS Inline Layout Module Level 3​

www.w3.org

CSS Grid Layout Module Level 2​

www.w3.org

CSS Multi-column Layout Module Level 1​

www.w3.org

CSS Layout API Level 1​

www.w3.org

Layout_入门 精通 教程_w3cplus​

www.w3cplus.com

值、单位和颜色

CSS Values and Units Module Level 4​

www.w3.org

CSS Values and Units Module Level 3​

www.w3.org

CSS Color Module Level 3​

www.w3.org

图解CSS:CSS 的值和单位_CSS, 图解CSS, 长度单位 教程_w3cplus​

www.w3cplus.com

定位

CSS Positioned Layout Module Level 3​

www.w3.org

position_入门 精通 教程_w3cplus​

www.w3cplus.com

层叠和继承

图解CSS:CSS层叠和继承_CSS, 图解CSS 教程_w3cplus​

www.w3cplus.com

聊聊CSS中的层叠相关概念_CSS, z-index, BFC 教程_w3cplus​

www.w3cplus.com

transform/transition/animation相关的

CSS Transforms Module Level 1​

www.w3.org

CSS Transitions​

www.w3.org

CSS Animations Level 1​

www.w3.org

https://www.w3cplus.com/blog/tags/95.html​

www.w3cplus.com

transition_入门 精通 教程_w3cplus​

www.w3cplus.com

Web动画_入门 精通 教程_w3cplus​

www.w3cplus.com

另外还有比较新的,比如:

  • CSS混合模式和滤镜
  • CSS绘制图形
  • CSS自定义属性
  • 不一一列出

看到这些,估计为什么写不出好的CSS有一定的原因所在了。刚才也说过,同样一个效果,可能会有N种组合方式,甚至 同一个人在不同时间写同一个效果都会有N种组合方式。因为CSS就是一种七巧板

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110910624.jpg" data-caption="" data-size="normal" data-rawwidth="427" data-rawheight="241" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110911655.jpg" class="origin_image zh-lightbox-thumb" width="427" data-original="https://pic4.zhimg.com/v2-a36a707ee5b6b47d19374321eb321952_r.jpg"/>

不够成体系

其实写CSS还是有很多方法论的,比如有名的:

  • OOCSS

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110913961.jpg" data-caption="" data-size="normal" data-rawwidth="1000" data-rawheight="366" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110915803.jpg" class="origin_image zh-lightbox-thumb" width="1000" data-original="https://pic3.zhimg.com/v2-d06fb01e70c923c3417cf86a677a003e_r.jpg"/>

  • SMACSS

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110916649.jpg" data-caption="" data-size="normal" data-rawwidth="1000" data-rawheight="366" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110917647.jpg" class="origin_image zh-lightbox-thumb" width="1000" data-original="https://pic4.zhimg.com/v2-78e9299ba1786633fd50caded72bc528_r.jpg"/>

  • Atomic Design

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110919127.jpg" data-caption="" data-size="normal" data-rawwidth="1108" data-rawheight="454" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110920572.jpg" class="origin_image zh-lightbox-thumb" width="1108" data-original="https://pic4.zhimg.com/v2-e3a87508fce71a0fdf172af2e4ea5fb7_r.jpg"/>

除了前面提到的,还有其他的类似方法,比如BEM、SUITCSS、MCSS、AMCSS等。

借助这些优秀的方法论,可以让你的CSS变得更优雅些:

CSS架构_入门 精通 教程_w3cplus​

www.w3cplus.com

借助工具来帮你

到目前为止,写CSS不仅仅局限于CSS,可以使用一些CSS处理器或其他的工具来帮更简单的写CSS。

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110921370.jpg" data-caption="" data-size="normal" data-rawwidth="914" data-rawheight="334" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110923285.jpg" class="origin_image zh-lightbox-thumb" width="914" data-original="https://pic4.zhimg.com/v2-ab2c7ea061aa5ba581a2ddf3924e7b04_r.jpg"/>

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110924812.jpg" data-caption="" data-size="normal" data-rawwidth="720" data-rawheight="719" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110925435.jpg" class="origin_image zh-lightbox-thumb" width="720" data-original="https://pic4.zhimg.com/v2-fa64edf314813f1882d557d5c997e8ce_r.jpg"/>

平时也可以收集一些帮你撸码的利器

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110927133.jpg" data-caption="" data-size="normal" data-rawwidth="790" data-rawheight="926" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110928547.jpg" class="origin_image zh-lightbox-thumb" width="790" data-original="https://pic2.zhimg.com/v2-24f41e680eb311c8dff575981f76692a_r.jpg"/>

tools_入门 精通 教程_w3cplus​

www.w3cplus.com

眼界不够高

眼界不够高,看得少。这方面很简单,自己多看,多写。比如Codepen就是一个很好的地方:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110929265.jpg" data-caption="" data-size="normal" data-rawwidth="2376" data-rawheight="1738" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110930863.jpg" class="origin_image zh-lightbox-thumb" width="2376" data-original="https://pic3.zhimg.com/v2-6e1df27350d76aa0b418f03de2c038c4_r.jpg"/>

今天就写到这,感觉好长了.....

最后放上早期的一篇分享:

<img src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110932543.jpg" data-caption="" data-size="normal" data-rawwidth="2406" data-rawheight="1436" data-default-watermark-src="http://www.hmttv.cn/uploadfile/2024/0806/20240806110933733.jpg" class="origin_image zh-lightbox-thumb" width="2406" data-original="https://pic1.zhimg.com/v2-9468a45677ade79042c584ad2ef6a6f7_r.jpg"/>

写CSS的姿势_CSS 教程_w3cplus​

www.w3cplus.com

再给CSSer推荐学习CSS的好去处:

CSS-Tricks​

css-tricks.com

CSS3_入门 精通 教程_w3cplus​

www.w3cplus.com

张鑫旭-鑫空间-鑫生活​

www.zhangxinxu.com

ChokCoco - 博客园​

www.cnblogs.com

另外推荐几本CSS的书

<img src="https://pic2.zhimg.com/50/v2-e3dca328d69807447af0361dc8e32908_hd.jpg" data-caption="" data-size="normal" data-rawwidth="259" data-rawheight="328" data-default-watermark-src="https://pic3.zhimg.com/50/v2-11cf35a68249c85162f65a4ff2800190_hd.jpg" class="content_image" width="259"/>

<img src="https://pic3.zhimg.com/50/v2-6e2a0e0f95f2c3b77c76e13dc5b73e26_hd.jpg" data-caption="" data-size="normal" data-rawwidth="212" data-rawheight="280" data-default-watermark-src="https://pic4.zhimg.com/50/v2-2615788a104a1d77e1f22da17eb007f0_hd.jpg" class="content_image" width="212"/>

<img src="https://pic3.zhimg.com/50/v2-c29c9d8de69a08ebf4a7a6cf62666a4c_hd.jpg" data-caption="" data-size="normal" data-rawwidth="500" data-rawheight="609" data-default-watermark-src="https://pic2.zhimg.com/50/v2-e9c674761da7667f9b827d75e0d88adf_hd.jpg" class="origin_image zh-lightbox-thumb" width="500" data-original="https://pic3.zhimg.com/v2-c29c9d8de69a08ebf4a7a6cf62666a4c_r.jpg"/>

<img src="https://pic4.zhimg.com/50/v2-28662508c3310dc08173a52d311303bc_hd.jpg" data-caption="" data-size="normal" data-rawwidth="200" data-rawheight="200" data-default-watermark-src="https://pic2.zhimg.com/50/v2-ba483e1a6babac048892d9bf78742ee4_hd.jpg" class="content_image" width="200"/>

<img src="https://pic3.zhimg.com/50/v2-dc4bd14f4ffacd73b7cba1885bc1668b_hd.jpg" data-caption="" data-size="normal" data-rawwidth="200" data-rawheight="200" data-default-watermark-src="https://pic1.zhimg.com/50/v2-7b640425ba95da6b31105599c7fba2f6_hd.jpg" class="content_image" width="200"/>

学习从来不是一个人的事情,要有个相互监督的伙伴,工作需要学习前端或者为了入行、转行学习前端的伙伴可以私信回复小编“前端”领取全套免费前端学习资料、视频

EB前端现在是时下较火的编程语言之一,特别是对于自学来说连css的一些权重都不是很了解,针对这种情况小猿圈web前端讲师就讲讲css基础入门之权重,希望对你的前端学习有一定的帮助。

一、css权重是什么?

css权重指的是css6大基础选择符的优先级,优先级高的css样式会覆盖优先级底的css样式,优先级越高说明权重越高,反之亦然。

css6大基础选择器:

a)、id选择器(#box{})

b)、类选择器(.box{})

c)、属性选择器(a[href=http://www.xxx.com])

d)、伪类和伪对象选择器(:hoevr{}和::after{})

e)、标签类型选择器(div{})

f)、通配符选择器(*{})

优先级顺序从大到小:

内联样式 > ID 选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 元素(类型)选择器 = 伪元素选择器

二、css权重计算规则

计算css权重是有一定规则的,根据w3c制定的css规范,css权重计算规则如下:

a)、计算选择符中的id选择器的数量一个id选择器为一个a,一个a为100

b)、计算选择符中的类选择器、属性选择器以及伪类选择器的数量一个类选择器、属性选择器以及伪类选择器为一个b,一个b为10

c)、计算标签类型选择器和伪对象选择器的数量一个标签类型选择器、伪对象选择器为一个c,一个c为1

d)、忽略通配符选择器通配符选择器忽略不计

如图是一个css选择器权重的例子:

如果两个选择符的权重相同,则可依照”就进原则”来判断,最后定义的选择符会被采用。但尽量避免出现这种依靠定义的顺序决定选择符优先级的情况,因为在后续的维护中很难保证定义的顺序不会被打乱。

小猿圈web前端讲师认为:授之以鱼更授之以渔,想要学好web前端首先需要就是端正自己的学习态度,明确学习目标,这样才能坚持学习。想要了解更多关于前端方面的小伙伴,可以关注小猿圈每天的动态,会不定期更新互联网编程知识,希望对你的学习有一定的帮助。