2 min read

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).

  1. Inline Styles: Styles added directly to the element (e.g., style="color: red;").
    • Score: (1, 0, 0, 0)
  2. IDs: ID selectors (e.g., #header).
    • Score: (0, 1, 0, 0)
  3. Classes, Attributes, Pseudo-classes: Class selectors (.box), attribute selectors ([type="text"]), and pseudo-classes (:hover).
    • Score: (0, 0, 1, 0)
  4. Elements and Pseudo-elements: Type selectors (div, h1) and pseudo-elements (::before).
    • Score: (0, 0, 0, 1)

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, 0 beats 0, 99, 99, 99. (Inline style wins over any number of IDs).
  • 0, 1, 0, 0 beats 0, 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.

programming/css/css programming/css/selectors