Skip to main content

CSS Specificity - How It Works

Answer

CSS specificity determines which styles are applied when multiple rules target the same element. It's calculated as a hierarchy of selector weights.

Specificity Hierarchy

Specificity Calculation

Specificity is calculated as a tuple: (Inline, IDs, Classes, Elements)

SelectorIDsClasses/AttrsElementsScore
p0010,0,0,1
.class0100,0,1,0
p.class0110,0,1,1
#id1000,1,0,0
#id .class p1110,1,1,1
inline style---1,0,0,0

Examples

/* Specificity: 0,0,0,1 */
p {
color: blue;
}

/* Specificity: 0,0,1,0 - WINS over element */
.text {
color: green;
}

/* Specificity: 0,0,1,1 */
p.text {
color: red;
}

/* Specificity: 0,1,0,0 - WINS over classes */
#main {
color: purple;
}

/* Specificity: 0,1,1,1 */
#main p.text {
color: orange;
}
<p id="main" class="text">What color am I?</p>
<!-- Answer: orange (highest specificity: 0,1,1,1) -->

!important Override

p {
color: blue !important; /* Wins over everything except... */
}

.text {
color: red !important; /* Another !important with higher specificity wins */
}

/* !important on higher specificity wins */
#main {
color: green !important; /* This wins! */
}

What Doesn't Affect Specificity

/* These have same specificity (0,0,1,0) regardless of complexity */
.a {
}
.b {
}
.a.b.c.d.e {
} /* Still 0,0,5,0 - each class adds */

/* Pseudo-classes count as classes */
button:hover {
} /* 0,0,1,1 */
a:visited {
} /* 0,0,1,1 */

/* Pseudo-elements count as elements */
p::first-line {
} /* 0,0,0,2 */

Source Order (Tiebreaker)

When specificity is equal, the last rule wins:

.button {
color: blue;
}
.button {
color: red;
} /* Wins - same specificity, comes last */

Specificity Best Practices

/* ❌ Avoid: Over-specific selectors */
body div#main article ul li.item a.link {
}

/* ✅ Good: Flat, low-specificity selectors */
.nav-link {
}
.card-title {
}

/* ❌ Avoid: !important chains */
.text {
color: blue !important;
}
.text {
color: red !important;
} /* Specificity war */

/* ✅ Prefer: Increase specificity intentionally */
.component .text {
color: red;
}

Quick Reference

!important > inline > #id > .class/[attr]/:pseudo > element > *for "universal"

Key Points

  • Specificity is calculated, not just "more selectors"
  • IDs beat any number of classes
  • Classes beat any number of elements
  • !important overrides everything (avoid when possible)
  • Equal specificity = last rule wins
  • Keep specificity low and flat for maintainability