Interview question and answer
Q: How to calculate the weight of CSS selector? (Or how is the priority of CSS selectors calculated?)
Answer: The calculation of CSS weight is divided into four levels a, b, c, d; the declaration defined in the style attribute of the HTML element belongs to the a level, the id selector belongs to the b level, the attribute selector, the class selector and the pseudo The class selector belongs to level c, and the type selector belongs to level d; among the four levels, level a has the highest weight value, and level d has the lowest weight value. The weight value is counted according to the number of occurrences of each level. If each level occurs once, it is counted once. The weight value is compared according to the numbers calculated from the four levels of a, b, c, d from high to low. If the value of the same level is PK, the subsequent comparison will not be performed. If the numbers of the same level are the same, continue to compare the numbers of the lower level. Some of these selectors do not participate in the priority calculation, including: general selector "*", negative pseudo-class: not selector, sub-class selector in combination selector, adjacent sibling selector, and normal sibling selection Device. However, the selector in the negative pseudo-type selector will participate in the selector priority calculation. The CSS declaration that contains
!important
is a special existence and does not participate in the calculation of the weight value. It is higher than the four levels of a, b, c, and d; when both contain!important
, the weight value will be calculated according to the matching rule of the selector. Whose weight value is high, whose style is applied.
basic concepts
CSS rules
CSS rules are composed of two main parts: selectors, and one or more declarations;
selector is usually an HTML element that needs to be styled; declares that consists of an attribute and a value. attribute is the style attribute you want to set. Each attribute has a value (attribute value), and the attribute and value are separated by a colon.
priority
The browser uses the priority to determine which attribute values are most relevant to an element, and apply these attribute values to the element. Priority is based on matching rules composed of different types of selectors.
again, the priority of 160d21012433bf is based on the matching rule composed of different types of selectors. We also use the picture example CSS rule
// 选择器『p』就是计算优先级的『匹配规则』
p { font-size:14px; background:#ff0;}
ul#nav li.active a { font-size:14px; }
body.ie7 .col_3 h2~h2 { font-size:16px; }
//『ul#nav li.active a』 和 『body.ie7 .col_3 h2~h2』 是计算优先级的匹配规则
Weights
The weight is determined by the value of each selector type in the matched selectors. The larger the number calculated by the weight, the higher the priority of the corresponding matching rule. If a CSS declaration is defined in two matching rules with equal priority, the CSS declaration in the last matching rule will be applied to the element according to the order of the matching rules in the CSS file.
example
<div id="id" class="class">我的字体大小</div>
#id {
font-size:18px;
}
.class {
font-size:16px;
}
The size of the final text is 18px. According to the calculation result of the selector type, the value of #id is: 1,0,0; the value of .class is: 0,1,0.
For the calculation process, let’s press the button first, and we will explain it later
Click to view code sample
Matching rules with equal priority
.class{
font-size:18px;
}
[class='class']{
font-size:16px;
}
The final text size is 16px. According to the calculation result of the selector type, the value of .class is: 0,1,0, and the value of [class='class'] is: 0,1,0.
Click to view code example
Specificity
Above we said that the calculation result of #id is: 1, 0, 0; the calculation result of .class and [class='class'] is: 0, 1, 0. Why is such a value calculated? This is the specificity we are talking about, English specificity. The following quotes the original W3C official text:
A selector's specificity is calculated as follows:
- count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element's "style" attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
- count the number of ID attributes in the selector (= b)
- count the number of other attributes and pseudo-classes in the selector (= c)
- count the number of element names and pseudo-elements in the selector (= d)
The specificity is based only on the form of the selector. In particular, a selector of the form "[id=p33]" is counted as an attribute selector (a=0, b=0, c=1, d=0), even if the id attribute is defined as an "ID" in the source document's DTD.
Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity.
The specific calculation rules of the selector are as follows:
- If CSS declares the style attribute from an HTML element, rather than a rule with a selector, the count is 1, otherwise it is 0; (In HTML, the value of the style attribute of an element is a style sheet rule. These rules have no selector; the element The style rule defined by the style attribute is represented by a in the specificity calculation, so usually in HTML, the specificity of the style sheet rule defined by the style attribute of the element is expressed as: a=1, b=0, c=0, d =0.)
- Count the number of id attributes in the selector, denoted by b
- Calculate the number of other attributes (including class attributes) and pseudo-classes in the selector, denoted by c
- Calculate the number of element names and pseudo-elements in the selector, denoted by d
The word "specificity" is really very, very difficult to understand. According to the semantics, I don't understand what it means. For a better understanding, I use "weight value" to mean "specificity".
Calculation example
* {} /* a=0 b=0 c=0 d=0 -> 权重值 = 0,0,0,0 */
li {} /* a=0 b=0 c=0 d=1 -> 权重值 = 0,0,0,1 */
li:first-line {} /* a=0 b=0 c=0 d=2 -> 权重值 = 0,0,0,2 */
ul li {} /* a=0 b=0 c=0 d=2 -> 权重值 = 0,0,0,2 */
ul ol+li {} /* a=0 b=0 c=0 d=3 -> 权重值 = 0,0,0,3 */
h1 + *[rel=up]{} /* a=0 b=0 c=1 d=1 -> 权重值 = 0,0,1,1 */
ul ol li.red {} /* a=0 b=0 c=1 d=3 -> 权重值 = 0,0,1,3 */
li.red.level {} /* a=0 b=0 c=2 d=1 -> 权重值 = 0,0,2,1 */
#x34y {} /* a=0 b=1 c=0 d=0 -> 权重值 = 0,1,0,0 */
style="" /* a=1 b=0 c=0 d=0 -> 权重值 = 1,0,0,0 */
Note: When the ID selector is used as an attribute selector, such as [id='id']
, the calculation of the weight value will be calculated based on the C level.
Weight value calculation rules
Weight value = a*num, b*num, c*num, d*num;
The calculation of the weight value There is a more common saying on the Internet: the style weight value defined by the style attribute is 1000, the weight value of an id selector is 100, the weight of an attribute and pseudo-class selector is expressed as 10, an element name and a pseudo element The weight value of is 1. such as:
According to the weight value calculation rules we said, in fact, the value of total value in the picture should be expressed as: 0,1,1,3. The direct use of the number 113 is just for the convenience of memory, but the comparison of the priority of the selector cannot be compared by numbers. For example: two matching rules, one is 11 attribute selectors, the other is 1 id selector, when their weight values are compared:
11 attribute selectors is 110, and the result of the second ID selector is 100. Obviously "11 attribute selectors" get the largest numerical value, is it the highest priority? Let's experiment:
HTML text
<div id='id' class='c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11'>
应用谁的样式
</div>
CSS style
#id {
background:red;
}
[id='id'][class~='c1'].c1.c2.c3.c4.c5.c6.c7.c8.c9.c10.c11{
background:yellow;
}
You can also click sample to try it yourself
Comparison of weight values
When two weights are compared, the weight values on the rank bits (for example, weights 1, 0, 0, 0 correspond to --> A, B, C, D) are compared step by step from A to D Instead of simply numbers + 100 numbers + 10 numbers + 1 numbers, in other words, the number of low-level selectors will not increase The level exceeds the priority of the high-level selector; please see the following figure:
summary
- The weight value is compared according to the level of a, b, c, d. If the value of the same level is the same, continue to compare to the lower level
- If the calculated weight values are the same, then which matching rule is at the end, the CSS declaration of which is applied
- !important is beyond the above weight value calculation rules, and has the highest priority.
The selector that does not participate in the calculation
Not all selectors participate in the calculation rules of the weight value, and some do not, including:
- Universal selector "*"
- Negative pseudo-class selector ":not"
- Combination selector "+, ~, >"
Negative pseudo-class selector: :not()
, although it is not weighted, the css selector written in it needs to be weighted.
!important
!important
is a special existence. !important
is not within the weight calculation range of the css selector. The reason why it can make the css selector take effect is because the browser will make special judgments when it !important
When multiple !important
needs to be compared, their weights will be calculated first and then compared. Generally speaking, the use of !important
is not recommended. But when we need to override the style defined in the style attribute, we can choose to use !important
.
other instructions
- Priority calculation ignores the distance in the DOM tree; for example:
html p
andbody p
the same weight value, who writes the CSS declaration later - Pseudo-class selector, attribute selector, and class selector have the same weight value
reference
Calculate the specificity of the selector CSS2
Assign attribute values, cascade, inherit CSS22
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。