# The cascade and specificity

> When two rules disagree: origin, layers, specificity, then order — and why !important is a smell.

Concept · The browser · https://levelcode.org/concepts/css-cascade

Several CSS rules often set the same property on the same element. The **cascade** decides which one wins by comparing these criteria in order. Each one is only a tie-breaker for the one before it.

1. **Origin and importance.** Normal author styles beat browser defaults. `!important` declarations beat normal ones.
2. **Cascade layers** (`@layer`). Rules in later layers beat earlier ones, and styles outside any layer beat all layers.
3. **Specificity.** The more specific selector wins.
4. **Order.** If everything else ties, the rule that appears last wins.

Inline `style=""` sits above every selector, so only `!important` beats it.

## Specificity

Count three things in a selector, written as (IDs, classes, elements):

| Selector | Specificity |
|---|---|
| `p` | (0, 0, 1) |
| `.card p` | (0, 1, 1) |
| `.card .title:hover` | (0, 3, 0) — pseudo-classes and attributes count as classes |
| `#main .title` | (1, 1, 0) |

Compare left to right. One ID beats any number of classes, and one class beats any number of elements. `:where()` adds zero specificity. `:is()` and `:not()` take the specificity of their most specific argument.

```css
#sidebar a { color: gray; }      /* (1,0,1) */
.nav-link.active { color: blue; } /* (0,2,0) — loses, even though it's later and more "meaningful" */
```

## Keeping it manageable

- **Style with single classes.** Keep specificity flat and low, so order decides and order is easy to reason about. Methodologies like BEM, [CSS Modules](https://levelcode.org/roadmaps/frontend/css-modules) and utility classes ([Tailwind](https://levelcode.org/roadmaps/frontend/tailwind-css)) all do this.
- **Avoid IDs in selectors.** One ID forces every override after it into a specificity arms race.
- **Treat `!important` as a smell.** It usually covers up a specificity problem, and the only way to override it is another `!important`. Reasonable uses are utility classes that must always win, and overriding third-party inline styles.
- **Use `@layer`** to make precedence explicit, for example `@layer reset, base, components, utilities;`. Then a later layer always wins, whatever its specificity.

Inheritance is separate. Properties like `color` and `font` pass down to children when nothing sets them, but any rule that targets the child, however weak, beats an inherited value.
