CSS Specificity
Specificity is the algorithm used by browsers to determine which CSS rule applies to an element when multiple rules match. It is essentially a scoring system.
1. The Hierarchy
The specificity score is calculated based on the types of selectors used. It is often represented as a tuple of four numbers: (Inline, ID, Class, Element).
- Inline Styles: Styles added directly to the element (e.g.,
style="color: red;").- Score:
(1, 0, 0, 0)
- Score:
- IDs: ID selectors (e.g.,
#header).- Score:
(0, 1, 0, 0)
- Score:
- Classes, Attributes, Pseudo-classes: Class selectors (
.box), attribute selectors ([type="text"]), and pseudo-classes (:hover).- Score:
(0, 0, 1, 0)
- Score:
- Elements and Pseudo-elements: Type selectors (
div,h1) and pseudo-elements (::before).- Score:
(0, 0, 0, 1)
- Score:
Note: The Universal selector (`), combinators (+,>,~, ), and negation pseudo-class (:not()) have no effect on specificity. (However, the selectors *inside*:not()` do count).*
2. Calculation Examples
| Selector | Score | Breakdown |
|---|---|---|
h1 |
0, 0, 0, 1 | 1 Element |
div p |
0, 0, 0, 2 | 2 Elements |
.nav |
0, 0, 1, 0 | 1 Class |
ul.nav li.active |
0, 0, 2, 2 | 2 Classes, 2 Elements |
#sidebar |
0, 1, 0, 0 | 1 ID |
#sidebar .nav a |
0, 1, 1, 1 | 1 ID, 1 Class, 1 Element |
3. How it Works
When two rules apply to the same element, the browser compares their specificity scores.
- It compares the values from left to right.
1, 0, 0, 0beats0, 99, 99, 99. (Inline style wins over any number of IDs).0, 1, 0, 0beats0, 0, 10, 0. (One ID wins over 10 classes).
Example:
/* Score: 0, 0, 0, 1 */
p {
color: red;
}
/* Score: 0, 0, 1, 0 */
.text {
color: blue;
}
/* Score: 0, 1, 0, 0 */
<a href='/?search=%23demo' class='obsidian-tag'>#demo</a> {
color: green;
}
<p id="demo" class="text">Hello</p>
The text will be green because the ID selector has the highest specificity.
4. The !important Exception
The !important rule overrides all other specificity rules.
p {
color: red !important; /* Wins even against inline styles */
}
<a href='/?search=%23demo' class='obsidian-tag'>#demo</a> {
color: green;
}
Best Practice: Avoid using !important unless absolutely necessary (e.g., overriding 3rd party library styles that you cannot change otherwise). It breaks the natural cascading of stylesheets and makes debugging difficult.