🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 简介 浏览器通过优先级来判断哪一些属性值与一个元素最为相关,从而在该元素上应用这些属性值。优先级是基于不同种类选择器组成的匹配规则。 <br> <br> # 按显式权重对应用到给定元素的所有声明排序 计算的过程指的是用户代理(浏览器只是用户代理的一种“实例”)在渲染HTML的时候,对CSS进行层叠计算的过程。 层叠按照以下标准对声明进行排序,按优先级降序排列: 1. Transition声明 2. 用户浏览器的 important 声明 3. 用户的important声明 4. 作者的important声明 5. Animation声明 6. 作者的普通声明 7. 用户的普通声明 8. 用户代理的普通声明 <br> 假设我们的用户代理是Chrome浏览器,那么当我们要计算A:<div class="taobao"></div>的padding值的时候,会有这么一个排序过程(简化): > > 1. 浏览器中对该标签的``padding``默认值 > 2. 开发者对该标签的 ``padding`` 进行声明的值 > 3. 浏览器中对该标签的 ``padding`` 进行 **!important** 声明的值 > 4. 开发者对该标签的 ``padding`` 进行 **!important** 声明的值 <br> ~~~ <div class="taobao_com" id="taobao_com" data-show="true"> <div class="taobao"></div> <p>taobao.com</p> </div> div{ padding:1px; } .taobao_com{ padding:12px; } div .taobao{ padding:123px; } .taobao_com .taobao{ padding:1234px; } ~~~ 上面分别写了4条padding的的声明,但都会被排在层叠顺序的开发者对该标签的 padding 进行声明的值之中,而且padding没有更高权重的声明了,那么就会对这个声明队列里的声明进行优先级的计算。 <br> # 按特殊性对应用到给定元素的所有声明排序 优先级就是分配给指定的CSS声明的一个权重,它由匹配的选择器中的每一种选择器类型的数值决定。 <br> 而当优先级与多个CSS声明中任意一个声明的优先级相等的时候,CSS中最后的那个声明将会被应用到元素上。 <br> 当同一个元素有多个声明的时候,优先级才会有意义。因为每一个直接作用于元素的CSS规则总是会接管/覆盖(take over)该元素从祖先元素继承而来的规则。 > 注意: 文档树中元素的接近度 对优先级没有影响。 <br> ## 计算 选择器的特异性是针对给定元素计算的,如下所示: 1. **类型选择器**(例如, h1)和**伪元素** (例如, ::before)**(= A)** 2. **类选择器**(例如,`.example`),**属性选择器**(例如, `[type="radio"]`),**伪类**(例如, :hover)**(= B)** 3. **ID选择器**(例如, #example)**(= C)** 4. **内联样式**比所有其他声明的级别都高 **通配选择符**(universal selector)(`*`),**关系选择符**(combinators) (`+`, `>`, `~`, '')  和**否定伪类**(negation pseudo-class)(`:not()`)对优先级没有影响。(但是,在 **:not() 内部声明** 的选择器是会影响优先级)。 <br> <br> 把权重分为 A,B,C 三个级别,A > B > C , A,B,C 直接各自计算。优先计算 A 的权重,如果相等会计算 B 的权重,以此类推。 例子 ~~~ * /* a=0 b=0 c=0 */ LI /* a=0 b=0 c=1 */ UL LI /* a=0 b=0 c=2 */ UL OL+LI /* a=0 b=0 c=3 */ H1 + *[REL=up] /* a=0 b=1 c=1 */ UL OL LI.red /* a=0 b=1 c=3 */ LI.red.level /* a=0 b=2 c=1 */ #x34y /* a=1 b=0 c=0 */ #s12:not(FOO) /* a=1 b=0 c=1 */ .foo :is(.bar, #baz) /* a=1 b=1 c=0 */ ~~~ <br> <br> ## :not 伪类 `:not`否定伪类在优先级计算中不会被看作是伪类. 事实上, 在计算选择器数量时还是会把其中的选择器当做普通选择器进行计数. ## 例子 ~~~ <div class="outer"> <p>This is in the outer div.</p> <div class="inner"> <div id="haha"> <p> ssss</p></div> <p>This text is in the inner div.</p> </div> </div> ~~~ <br> 不声明:not ~~~ div.outer p { color:orange; } div:not(.outer) p { color: blueviolet; } div #haha p { color: blue; } ~~~ ![](https://box.kancloud.cn/f54fceed8657d732d93627f2db9fc54e_299x129.png) <br> :not 在普通样式之后 ~~~ div.outer p { color:orange; } div:not(.outer) p { color: blueviolet; } div #haha p { color: blue; } div:not(#hehe) p{ color: red; } ~~~ ![](https://box.kancloud.cn/15a69650209795d713c1bced267509a2_261x131.png) <br> :not 在普通样式之前 ~~~ div.outer p { color:orange; } div:not(.outer) p { color: blueviolet; } div:not(#hehe) p{ color: red; } div #haha p { color: blue; } ~~~ ![](https://box.kancloud.cn/7395fb23b4b8a6e539fef69223c28c1d_238x117.png) 可以看出,`div:not(#hehe) p` 与 `div #haha p` 同级,受声明顺序影响。 <br> <br> # 按出现顺序对应用到给定元素的所有声明排序 一个声明在样式表或文档中越后出现,它的权重就越大。如果样式表中有导入样式表的话,一般认为出现在导入样式表中的声明在前,主样式表中的所有声明在后。 <br> 若两个规则的权重,来源和特殊性完全相同,那么在样式表中后出现的一个会胜出。特别地,认为元素style属性中指定的样式位于文档样式表的最后,即放在所有其他规则的后面。不过,这一点已经没有意义了,因为CSS2.1明确指明内联样式的特殊性要高于所有样式表选择器。 <br> ## 加入CSS的方法 内联样式:`<div style="color:red;">` 内部样式表:`<style type="text/css">p{color:red;)</style>` 外部样式表:`<link href="sty.css" rel="stylesheet" type="text/css" />` 导入式样式表:`<style type="text/css">@import url("sty2.css");</style> ` <br> 关于内部样式表(即style元素`<style></style>`)与外部样式表以及引入式样式表,这三者的来源均属于创作人员,所以在声明的特殊性相同的情况下,会按它们出现的顺序决定谁最终胜出。谁出现在文档中的位置靠后,谁优先级高。而因为CSS2.1明确指明内联样式的特殊性要高于所有样式表选择器,所以最终比较的是内部样式表、外部样式表、导入式样式表的位置。 <br> <br> # 参考资料 [MDN - 优先级 ](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity)[真正理解"CSS选择器的优先级"](https://github.com/jincdream/jincdream.github.io/issues/14) [CSS Cascading and Inheritance Level 4](https://www.w3.org/TR/css-cascade-4/#cascading) CSS权威指南(第三版)