Specificity and the Cascade
When multiple CSS rules target the same element, specificity and source order decide which one wins — understanding these rules explains most "why isn't my CSS working" moments.
How Specificity Is Calculated
Specificity is calculated as a weighted score: inline styles win over everything, then ID selectors, then classes/attributes/pseudo-classes, then plain element selectors. A rule with higher specificity wins regardless of where it appears in the file.
p { color: blue; } /* specificity: 0-0-1 */
.text { color: green; } /* specificity: 0-1-0 — wins over the above */
#intro { color: red; } /* specificity: 1-0-0 — wins over both above */
<p id="intro" class="text">This text is red.</p>
The Cascade and !important
When specificity is equal, the rule that appears later in the stylesheet wins. The !important flag overrides normal specificity entirely, but should be used sparingly — it makes future overrides much harder and is a common source of CSS technical debt.
Common Mistakes
- Reaching for !important to fix a styling conflict instead of understanding why a more specific rule is winning.
- Assuming later rules always win, without accounting for a higher-specificity rule earlier in the file overriding them.
- Overusing ID selectors for styling, which creates very high specificity that's hard to override later.
- Not realising that inline styles beat almost any external CSS rule, including ones with !important on regular declarations.
Professional Tip
If you ever feel tempted to reach for !important, first check whether a more specific selector is winning unexpectedly, or whether your own selector is less specific than you assumed. Fixing the root cause keeps your CSS maintainable.
Your Turn
Write three conflicting rules for the same paragraph's colour — one by tag, one by class, one by id — and predict which will apply before checking in a browser.
Mini Quiz
Which typically has the highest specificity weight among these selector types?