How Specificity Works
Each CSS selector has a specificity score — a three-column value written as (a, b, c). The browser compares scores column by column, left to right. The rule with the highest score wins. If scores are equal, the rule declared last in the source wins (the cascade).
| Category | What counts | Score contribution |
|---|---|---|
| Column A — ID selectors | #id |
(1, 0, 0) |
| Column B — Class, attribute, pseudo-class | .class, [attr], :hover, :nth-child() |
(0, 1, 0) |
| Column C — Element, pseudo-element | div, p, a, ::before |
(0, 0, 1) |
| Inline style | style="..." attribute |
(1, 0, 0, 0) |
| Universal / combinators | *, >, +, ~, |
(0, 0, 0) |
/* Selector Score (a, b, c) */
p /* (0, 0, 1) — 1 element */
.intro /* (0, 1, 0) — 1 class */
#header /* (1, 0, 0) — 1 ID */
div p /* (0, 0, 2) — 2 elements */
.nav li /* (0, 1, 1) — 1 class, 1 element */
.nav li a /* (0, 1, 2) — 1 class, 2 elements */
#header .nav li a /* (1, 1, 2) — 1 ID, 1 class, 2 elements */
.card:hover /* (0, 2, 0) — 1 class, 1 pseudo-class */
input[type="text"] /* (0, 1, 1) — 1 attribute, 1 element */
ul li:first-child /* (0, 1, 2) — 1 pseudo-class, 2 elements */
#nav > ul > li > a:hover /* (1, 1, 3) — 1 ID, 1 pseudo-class, 3 elements */
Comparing Specificity
/* Which color wins? */
p { color: blue; } /* (0,0,1) */
.text { color: red; } /* (0,1,0) */
/* Winner: .text → red (0,1,0 beats 0,0,1) */
#main p { color: green; } /* (1,0,1) */
.section .text { color: orange; } /* (0,2,0) */
/* Winner: #main p → green (1 in column A wins regardless of B and C) */
/* Same specificity — last one in source wins */
.btn { background: blue; } /* (0,1,0) */
.cta { background: red; } /* (0,1,0) */
/*
!important
!important overrides all specificity — including inline styles. It adds a separate "important" layer above the normal specificity scale. When two !important declarations compete, the one with higher specificity wins.
/* !important beats everything in the normal cascade */
p { color: blue !important; } /* wins over: */
#main p { color: red; } /* even though (1,0,1) > (0,0,1) */
/* Two !important — specificity wins */
p { color: blue !important; } /* (0,0,1) with !important */
.text { color: red !important; } /* (0,1,0) with !important — wins */
/* Utility class pattern — legitimate use of !important */
.text-center { text-align: center !important; }
.hidden { display: none !important; }
.mt-0 { margin-top: 0 !important; }
The Cascade Order
When specificity is equal, the cascade applies — rules are resolved in this order (later stages override earlier ones):
1. Browser default stylesheet (user-agent styles)
2. User stylesheet (accessibility overrides in browser settings)
3. Author stylesheet (your CSS) — by order:
a. External stylesheets (in link order)
b. Internal