laitimes

When it comes to CSS selector weights, 99% of people get it wrong!

author:Flash Gene

The weight (specificity) of a CSS selector is a key factor in determining which selector's style will eventually take effect when multiple selectors are applied to the same element. However, there are some common misconceptions about the specificity of CSS selectors. This article will explore these misconceptions and help you understand the weight of CSS selectors.

When it comes to CSS selector weights, 99% of people get it wrong!

Misconception 1: Weight is a number

The weight of the CSS selector is not a number. Therefore, when calculating the weights of elements, it is not as simple as adding the weights to the values.

The weights of a CSS selector are made up of three parts, represented as (a, b, c), where a, b, and c represent the weights of the different selector types. The specific rules are as follows:

  • ID Selector: A style with a weight value of (1, 0, 0) that is matched by the element's ID selector.
  • Class selectors, attribute selectors, and pseudo-class selectors: The weight value is (0, 1, 0), and the class selector (e.g., .example), the attribute selector (e.g., [type="text"]), and the pseudo-class selector (e.g., hover) have the same weight.
  • Element Selector and Pseudo Element Selector: The weight value is (0, 0, 1), and the element selector (e.g., p) and pseudo element selector (e.g., :before) have the same weight.

Note: Wildcard selectors (such as *), sub-selectors (such as >), adjacent sibling selectors (such as +), and sibling selectors (such as ~) do not contribute to the weight, i.e. they have a weight of (0,0,0).

Weight calculation rules:

  1. Compare from left to right: compare the highest bit first (inline style), if the same, then the next bit, and so on. For example, (1, 0, 0) has a higher priority than (0, 1, 0), while (0, 1, 0) has a higher priority than (0, 0, 1).
  2. Weight add-on: The weights of each component are calculated independently and are not additive. For example, having two class selectors (.class1.class2) in a selector does not change its weight to (0,2,0), but remains (0,1,0). Similarly, a selector with an ID selector and a class selector (#id.class) has a weight of (1,1,0) instead of (2,0,0).
  3. !important rule: If !important is used in the declaration, it overrides all other specificities. However, it is important to note that !important only works in styles from the same source. If a !important rule from a user-agent stylesheet (the browser's default style) or a user stylesheet conflicts with a normal rule from an author stylesheet, then the !important rule for the user-agent stylesheet or the user-style sheet takes effect.
  4. Order of origin: If both rules have the same specificity and neither uses !important, then the later rule overrides the first rule (i.e., the "first-come-first" principle).

For example:

/* 权重为 (0,0,1) */  
div { color: red; }  

/* 权重为 (0,1,0) */  
.class1 { color: green; }  

/* 权重为(1,0,0) */  
#id1 { color: blue; }  

/* 权重为(1,1,0)(因为 ID 选择器的权重高于类选择器)*/  
#id1.class1 { color: purple; }  

/* 权重为(0,1,0),因为只有一个类选择器 */  
.class1 { color: red; }  
  
/* 权重为(0,1,0),即使有两个类选择器,但它们的权重不会相加 */  
.class1.class2 { color: blue; }  
  
/* 权重为(1,1,0),因为一个ID选择器和一个类选择器的组合 */  
#id1.class1 { color: green; }  
  
/* 权重为(0,1,0),因为有三个类选择器,但每个类选择器的权重仍然是(0,1,0) */  
.class1.class2.class3 { color: purple; }
           

In the example above, even if the selector contains multiple identical components (such as a class selector), the weights of each component are still independent and do not add-on. Therefore, in the event of a selector conflict, the selector with higher specificity will override the selector with lower specificity. If the specificity is the same, the rule that comes later overrides the rule that comes first (i.e., the "first-come-first" principle).

Let's take a closer look at the last example:

For the selector .class1.class2.class3, its specificity (weight) is calculated as follows:

该选择器包含三个类选择器(.class1、.class2 和 .class3)。

In CSS specificity calculations, each class selector contributes a specificity value of (0,1,0).

Since specificity values don't accumulate across types, we only need to focus on the number on the class selector's bit (i.e., the third bit).

In this example, there are three class selectors, but each class selector still has a value of 1 on the class selector bit.

However, this does not mean that the three class selectors add up to 3. In fact, we don't add the values on the class selector bit in the specificity calculation of the selector. We just need to keep track of how many class selectors exist (in this case, three). However, when describing specificity, we usually (0,3,0) don't write such a notation directly, because according to the standard specificity notation, we only need to point out that there are three units on the class selector bit (i.e., 0,1,0 appears three times).

However, for the sake of clarity and to avoid confusion, when we talk about the specificity of such a selector consisting of multiple homogeneous selectors, we might say that its specificity "weight" on the class selector bit is equivalent to (0,3,0) (although this is not a standard notation). However, when comparing the specificity of a selector, we just need to remember that it has three units at the class selector bit.

Thus, the specificity (weight) of .class1.class2.class3 is (0,1,0) according to the standard notation (but since there are three class selectors, the "equivalent weight" on the class selector bit can be understood as three units).

Misconception 2: Using the style attribute increases the weight

A lot of people think that using the style attribute directly on HTML elements to define CSS styles will increase style weight.

Using the style attribute directly on an HTML element does not increase the specificity of the element. In fact, the style property defines the style that takes precedence, which is often referred to as "inline style" or "inline style". But this high priority does not come from the calculation of specificity, but from a special rule in the CSS cascading and conflict resolution mechanism.

The style property (inline style) takes precedence over any other style rule defined in a style sheet, regardless of the selector used (ID, class, element, etc.) in the CSS stack. Note, however, that this priority and specificity are two different concepts.

  • Specificity: The mechanism used to determine which style rules are applied to an element. Specificity is a three-part weight value, and when two or more style rules apply to the same element, the browser decides which rule will ultimately be applied to that element based on the specificity of those rules.
  • Priority: The mechanism used to determine which style rule will take effect with the same specificity. In this case, the priority is determined in the following order, where the user style overrides the user agent style, and the author style overrides the user style (unless the user style uses !). important):
    • Inline styles
    • Author's stylesheet
    • Important authorship style
    • Ordinary author style
    • User Agent Stylesheet: The default style of the browser, such as the default font size and color.
    • User Styles: Styles that can be customized through browser settings or extensions.
    • 作者样式(Author Styles):在样式表中定义的样式。

Among author-defined styles, inline styles have the highest priority, even if other style rules have higher specificity. Note, however, that this does not mean that inline styles are more specific; It's just higher than the other styles in priority. Therefore, the style attribute does not increase the weight of the element.

Misconception 3: Use! important, will increase the weight

We know that using !important in CSS will give the style the highest priority. However, using !important in CSS declarations does not increase its specificity.

Specificity (weight) is a weighting system determined by the selector type that determines which rule will be applied first when multiple style rules are applied to the same element. Whereas! important is an override mechanism that changes the priority of a declaration so that it has a higher weight in the cascading order of CSS.

When the browser needs to determine the final style of an element, it does so by following these steps:

  1. Calculate specificity: First, the browser calculates the specificity of each CSS rule applied to that element. The more specific the rule, the higher its priority.
  2. Compare sources: If two or more rules have the same specificity, the browser further compares the sources of those rules. Typically, user-defined styles, such as browser extensions or user stylesheets, override author-defined styles (i.e., stylesheets for web page developers), while author-defined styles override user-agent styles (i.e., browser-default styles).
  3. Consider! important: If two or more rules have the same specificity and origin, and at least one of them is used! important, you use ! The important rule will override the unused! important.
  4. Order of comparison: If two or more rules have the same specificity, origin, and neither is used! important, or both! important, the last defined rule overwrites the previously defined rule.

Therefore, !important does not change specificity, but rather serves as an additional basis for prioritization after the specificity comparison. Use! Important should be cautious as it breaks the cascading and specificity rules of CSS, making styles more difficult to maintain and debug. Where possible, it's best to avoid it by optimizing selectors and organizing style rules! important。

AUTHOR: CUGGZ

Source-WeChat public account: front-end treasure

Source: https://mp.weixin.qq.com/s/cBYe7LDdX35nlYwdHLQKMQ