深入理解css选择器的优先级
本文章转载于jin-c
文章原地址为https://juejin.im/post/5abc4fd7f265da237b2228ee
Jin_C2018年03月29日阅读 588真正理解"CSS选择器的优先级"
当我们在讨论CSS选择器优先级的时候,我们再讨论什么?
其实很多人都对此有点模糊,那我换个方式问: 一个CSS属性的最终值是怎么来?
回答 : CSS属性的最终值是通过层叠计算得来的。
那什么是层叠计算呢?
我通俗的理解,其实就是先计算再重叠。
层叠是CSS的一个基本特征,它是一个定义了如何合并来自多个源的属性值的算法。它在CSS处于核心地位,CSS的全称层叠样式表正是强调了这一点。
计算过程
计算的过程指的是用户代理(浏览器只是用户代理的一种“实例”)在渲染HTML的时候,对CSS进行层叠计算的过程(这里不讨论浏览器的渲染、重绘等触发时机)。
为了方便理解,这里只针对一个属性值(
padding)进行讨论,其他的属性值都是一样的过程。
demo:
<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; } 复制代码
在属性的计算之前,会对每个文档元素的每个属性上的值进行排序 (W3C文档地址):
1. Transition declarations [CSS3-TRANSITIONS] 2. Important user agent declarations 3. Important user declarations 4. Important override declarations [DOM-LEVEL-2-STYLE] 5. Important author declarations 6. Animation declarations [CSS3-ANIMATIONS] 7. Normal override declarations [DOM-LEVEL-2-STYLE] 8. Normal author declarations 9. Normal user declarations 10.Normal user agent declarations 复制代码
排序靠前的会比靠后的优先级要高。 1 > 2 > 3 > 4 > 5 ...
假设我们的用户代理是Chrome浏览器,那么当我们要计算
A:<div class="taobao"></div>的
padding值的时候,会有这么一个排序过程(简化):
1. 浏览器中对该标签的``padding``默认值 2. 开发者对该标签的 ``padding`` 进行声明的值 3. 浏览器中对该标签的 ``padding`` 进行 **!important** 声明的值 4. 开发者对该标签的 ``padding`` 进行 **!important** 声明的值 复制代码
那么在demo里面,分别写了4条
padding的的声明,但都会被排在层叠顺序的开发者对该标签的
padding进行声明的值之中,而且
padding没有更高权重的声明了,那么就会对这个声明队列里的声明进行优先级的计算。
所以,!important 跟选择器优先级是什么关系?
优先级的计算
优先级的计算首先是 选择器权重 的优先级计算,然后是 声明先后顺序 的优先级计算。
选择器优先级的权重计算
这时候,才到了选择器优先级登场。
选择器的权重并不是网上很多人说的
选择器通过权重值 1(div等)、10(class)、100(id)
这样的方式进行的,这只是别人理解出来的东西,真正的计算原理可以翻阅W3C文档选择器权重的计算。
文档指出:
A selector’s specificity is calculated for a given element as follows:
1.count the number of ID selectors in the selector (= A) 2.count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= B) 3.count the number of type selectors and pseudo-elements in the selector (= C) 4.ignore the universal selector
文档也给了例子:
Examples: * /* 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 :matches(.bar, #baz) /* Either a=1 b=1 c=0 or a=0 b=2 c=0, depending on the element being matched. */ 复制代码
大致意思就是,把权重分为了 A,B,C 三个级别,A > B > C , A,B,C 直接各自计算。也就是会优先计算 A 的权重,如果相等会计算 B 的权重,以此类推。
所以才有了100、10、1的说法,但很不准确。
结合之前的demo,我们来计算下权重值:
1:
div { /*type selectors*/ padding:1px; /*a = 0 , b = 0 , c = 1*/ } 复制代码
2:
.taobao_com{ /*class selectors*/ padding:12px; /*a = 0 , b = 1 , c = 0*/ } 复制代码
3:
div .taobao{ /*type selectors + class selectors*/ padding:123px; /*a = 0 , b = 1 , c = 1*/ } 复制代码
4:
.taobao_com .taobao{ /* class selectors + class selectors */ padding:1234px; /*a = 0 , b = 2 , c = 0*/ } 复制代码
由于A位相等,B位差异的最大值在 4 ,得到的结果将会是 第4条声明 胜出: 1. a = 0 , b = 0 , c = 1 2. a = 0 , b = 1 , c = 0 3. a = 0 , b = 1 , c = 1 4. a = 0 , b = 2 , c = 0
声明先后顺序
当 A 、B 、C 所计算的权重都相等时(ABC三个值相等)相等时,后面声明的值将会是最终的计算值。
最终得到了CSS属性的值。
- css选择器优先级深入理解
- 深入理解CSS选择器优先级
- css选择器优先级深入理解
- [转]css选择器优先级深入理解
- css选择器优先级深入理解
- 深入理解CSS选择器优先级的计算
- 关于选择器优先级的误解[刷新三观,深入理解选择器优先级]
- 深入理解this机制系列第二篇——this绑定优先级
- Spring框架学习-深入理解AOP02----AOP简介,AspectJ,AOP基于注解和XML配置(5种通知,切面优先级)
- Spring4深入理解AOP02----AOP简介,AspectJ,AOP基于注解和XML配置(5种通知,切面优先级)
- 深入理解this机制系列第二篇——this绑定优先级
- Android EventBus3.0深入理解 二 粘性消息和优先级
- PHP运行模式的深入理解
- 深入理解计算机系统--异常
- 【Android基础】Activity深入理解(二)——Activity栈和加载模式
- 深入理解JavaScript中的箭头函数
- 深入理解C++中的mutable关键字
- 深入理解JVM内幕
- java 23种设计模式 深入理解
- 深入理解Spark之RDD的款依赖和窄依赖