CSS Specificity
CSS Specificity is a very important concept. When multiple CSS rules apply to the same element, the browser needs a way to decide which rule ultimately takes effect. This decision process is based on Specificity.
Specificity can be thought of as the "weight" or "score" of a selector. The selector with the higher weight is more likely to have its styles applied.
Specificity Calculation Rules
The browser determines specificity by calculating four parts of a selector, which can be represented as (a, b, c, d):
- a (Inline Styles): If the style is written in the HTML element's
styleattribute (inline style), then a=1, otherwise a=0. - b (ID Selectors): Counts the number of ID selectors (
#id) in the selector. - c (Class, Attribute, and Pseudo-class Selectors): Counts the number of class selectors (
.class), attribute selectors ([type="text"]), and pseudo-classes (:hover) in the selector. - d (Element and Pseudo-element Selectors): Counts the number of element selectors (
div) and pseudo-elements (::before) in the selector.
Comparison Rule: Compare the values of a, b, c, d from left to right. The first non-zero value that is larger wins. For example, the specificity of (0, 1, 0, 0) is higher than (0, 0, 10, 0) because the value of b (1) is greater than 0, and subsequent values are not compared.
Examples
| Selector | Calculation (a, b, c, d) | Specificity | Explanation |
|---|---|---|---|
p | (0, 0, 0, 1) | 1 | 1 element selector |
p.red | (0, 0, 1, 1) | 11 | 1 class selector, 1 element selector |
#my-id | (0, 1, 0, 0) | 100 | 1 ID selector |
div#my-id | (0, 1, 0, 1) | 101 | 1 ID, 1 element selector |
a:hover | (0, 0, 1, 1) | 11 | 1 pseudo-class, 1 element selector |
ul li a.active | (0, 0, 1, 3) | 13 | 1 class, 3 element selectors |
[type="button"] | (0, 0, 1, 0) | 10 | 1 attribute selector |
style="..." | (1, 0, 0, 0) | 1000 | Inline style |
Special Rules
1. !important
Adding !important to the end of a style declaration makes it override any other declaration, regardless of its specificity. !important breaks the normal cascading rules and should be avoided as much as possible. It is usually only considered in special cases, such as when you need to override third-party libraries or inline styles.
p {
color: blue !important;
}
p#my-id {
color: red; /* This rule will not take effect */
}2. Universal Selector and Combinators
- The universal selector (
*) has a specificity of 0(0, 0, 0, 0). - Combinators (
+,>,~,) themselves do not increase specificity.
3. :not() Pseudo-class
The :not() pseudo-class itself does not increase specificity, but the selector inside its parentheses is calculated normally.
Resolving Specificity Conflicts
- Increase Selector Specificity: The most direct way is to create a more specific selector than the existing rule. For example, use
div.my-classinstead of.my-class. - Use Source Order: If two selectors have exactly the same specificity, the rule that appears later in the style sheet wins.
- Avoid
!important: Unless absolutely necessary. - Use Classes: Try to use classes to define styles and avoid using IDs for styling because IDs have very high specificity and are hard to override.
Understanding specificity is a key skill for debugging CSS issues. When you find that a style is not working as expected, the first thing you should check is whether there is another rule with higher specificity overriding it.