The calculation of selector specificity
Calculation of Selector Specificity
The specificity of CSS selectors determines which rule will be applied when multiple rules target the same element. Specificity is a weighting system that calculates the weight of different parts of a selector to determine the final applied style.
Specificity Weight Rules
Selector specificity consists of four parts, listed in order of importance from highest to lowest:
!important
declarations- Inline styles (style attribute)
- Number of ID selectors
- Number of class selectors, attribute selectors, and pseudo-classes
- Number of element selectors and pseudo-elements
The calculation method is as follows:
/* Specificity calculation example */
#header .nav li.active a:hover {
/* ID selector: 1 (#header)
Class selectors: 2 (.nav, .active)
Pseudo-class: 1 (:hover)
Element selectors: 2 (li, a)
Specificity value: 0,1,3,2 */
color: red;
}
Specificity Calculation Examples
Let's look at some concrete examples to understand specificity calculation:
/* Example 1 */
div { color: blue; } /* 0,0,0,1 */
.container div { color: green; } /* 0,0,1,1 */
#main .container div { color: red; } /* 0,1,1,1 */
div#main .container div { color: black; }/* 0,1,1,2 */
In this example, the last rule has the highest specificity because it contains one ID selector, one class selector, and two element selectors.
Handling Special Cases
!important Rule
!important
overrides all other specificity rules:
div {
color: red !important; /* This will override all other color declarations */
}
#special-div {
color: blue; /* Even though ID selectors have higher specificity, this won't take effect */
}
Inline Styles
Inline styles have higher specificity than rules in external stylesheets:
<div style="color: purple;">This text will be purple</div>
Even if there's a CSS rule like this:
div#special {
color: red;
}
Impact of Selector Combinations
Different types of selector combinations affect the final specificity:
/* Example 2 */
ul#nav li.active a { color: orange; } /* 0,1,1,3 */
#nav li.active a { color: yellow; } /* 0,1,1,2 */
ul li a { color: green; } /* 0,0,0,3 */
In this example, the first rule wins because it has one ID selector, one class selector, and three element selectors.
Inheritance and Specificity
Inherited styles have the lowest specificity, even lower than the universal selector:
body {
color: black;
}
* {
color: red; /* This will override the inherited black */
}
div {
color: inherit; /* Explicit inheritance has higher specificity than the universal selector */
}
Practical Recommendations
- Avoid using
!important
as it makes debugging difficult - Prefer class selectors over ID selectors to improve style reusability
- Keep selectors as simple as possible and avoid excessive nesting
- When overriding styles, consider increasing selector specificity rather than using
!important
Complex Case Analysis
Let's examine a more complex example:
<div id="page" class="dark-theme">
<section class="content">
<p class="highlight">Sample text</p>
</section>
</div>
Corresponding CSS:
#page .content p { color: blue; } /* 0,1,1,1 */
div.dark-theme section p { color: gray; } /* 0,0,2,2 */
.highlight { color: yellow; } /* 0,0,1,0 */
p { color: black; } /* 0,0,0,1 */
In this case, the first rule wins because it has the highest specificity value (0,1,1,1).
Specificity of Pseudo-classes and Pseudo-elements
Pseudo-classes and pseudo-elements have different weights in specificity calculation:
a:hover { color: red; } /* 0,0,1,1 */
a:first-child { color: blue; } /* 0,0,1,1 */
a::before { content: "→"; } /* 0,0,0,2 */
Pseudo-classes (:hover, :first-child, etc.) have the same weight as class selectors, while pseudo-elements (::before, ::after, etc.) have the same weight as element selectors.
Specificity of Attribute Selectors
Attribute selectors have the same specificity as class selectors:
input[type="text"] { border: 1px solid #ccc; } /* 0,0,1,1 */
input.text-field { border: 1px solid red; } /* 0,0,1,1 */
If both rules target the same element, the latter rule will override the former.
Universal and Combinator Selectors
The universal selector (*) and combinators (+, >, ~) do not affect specificity:
body > div > p { color: green; } /* 0,0,0,2 */
body div p { color: blue; } /* 0,0,0,2 */
* p { color: red; } /* 0,0,0,1 */
In this example, the first two rules have equal specificity, so the latter will take effect. The third rule has the lowest specificity.
Handling Equal Specificity
When multiple rules have equal specificity, CSS cascade rules determine which style is applied:
- Later-defined rules override earlier-defined rules
- More specific rules (e.g., those with more selectors) override less specific rules
!important
rules in user stylesheets override!important
rules in author stylesheets
/* Example */
.nav li { color: blue; }
.menu li { color: red; } /* This will take effect because it's defined later */
Debugging Specificity Issues
When styles don't apply as expected, follow these debugging steps:
- Check if the element is targeted by the correct selector
- Calculate the specificity of each rule
- Check for
!important
declarations - See if inline styles override CSS rules
- Use browser developer tools to inspect applied styles and overrides
Performance Considerations
Although modern browsers are well-optimized, overly complex selectors can still impact performance:
/* Not recommended - overly complex selector */
body > div#main > ul.nav > li.active > a:hover { ... }
/* Recommended - simpler selector */
.nav-link.active:hover { ... }
Simple class selectors generally offer better performance and are easier to maintain.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:相邻兄弟选择器与通用兄弟选择器
下一篇:选择器性能优化原则