cssspecificitycascade

Understanding CSS Specificity and Conflict Resolution

CSS specificity conflicts are the root cause of most unexpected styling bugs — understanding the three-number system makes them predictable.

4 min read

Related Tool

CSS Specificity Calculator

Open tool

The Three-Number System

Every CSS selector produces a specificity score expressed as three numbers: (IDs, Classes+Attributes+Pseudoclasses, Elements+Pseudoelements). Higher numbers win. The comparison is left-to-right — a selector with any ID beats a selector with any number of classes, regardless of class count.

Examples:

  • div → (0, 0, 1)
  • .card → (0, 1, 0)
  • #header → (1, 0, 0)
  • #header .nav a → (1, 1, 1)

Common Traps

!important overrides all specificity and source order. Once it appears in a codebase it spreads — you need !important to override !important. Avoid it except for utility classes designed to always win (like .hidden { display: none !important }).

Inline styles have implicit specificity (1, 0, 0, 0) — higher than any stylesheet selector. Avoid inline styles in component-based UIs.

Chained class selectors (.card.featured) have specificity (0, 2, 0) and can cause surprising overrides of ID-based selectors in some architectures.

Writing Less-Specific CSS

Flatter selectors are easier to override and reason about. Prefer a single class selector over a tag+class selector. Avoid nesting selectors more than two levels deep. In component-based frameworks, scope styles to the component rather than increasing specificity to avoid collisions.

A specificity calculator shows the score for any selector before you write it.