CSS Specificity: Why Your Styles Aren't Applying, Explained Properly
A four-part score, calculated per selector, decides which rule wins — not the order you wrote them in, and not how many !important you're willing to stack.
"Why isn't my CSS applying" is, more often than not, a specificity problem — a different rule with a higher specificity score is winning, silently, with no error and no warning.
The actual scoring system
Every selector gets a specificity score with three real components, compared in order: ID selectors (`#header`), then class/attribute/pseudo-class selectors (`.button`, `[type="text"]`, `:hover`), then element/pseudo-element selectors (`div`, `::before`). More of a higher-priority component always beats any amount of a lower one — ten element selectors combined still lose to a single class selector.
.card .title { color: blue; } /* 2 classes → specificity (0,2,0) */
#main h2 { color: red; } /* 1 id, 1 element → specificity (1,0,1) */
/* #main h2 wins — the id component outranks any number of classes */Why inline styles and `!important` are escape hatches, not tools
An inline `style="..."` attribute beats every selector-based rule regardless of specificity — it isn't even part of the same scoring system, it simply outranks all of it. `!important` goes a step further and overrides even that. Both exist as genuine emergency escape hatches (overriding a third-party library's inline styles you can't otherwise touch) — reaching for either as a routine way to "win" a specificity fight is exactly how a codebase ends up in an arms race where every future style needs its own `!important` just to have a chance.
How Tailwind sidesteps this problem structurally
Every Tailwind utility class has (roughly) the same specificity — one class selector each — so two utility classes on the same element resolve by CSS source order, not an unpredictable specificity fight. That's a real, structural reason "specificity wars" are a rare complaint in a Tailwind codebase specifically, not just a stylistic preference — it's covered in depth in this series' "why utility-first CSS won" post.