@layer & Specificity

Predictable Cascade With base/components/utilities

@layer & Specificity

Tailwind organizes CSS into native cascade layers so utilities reliably win without resorting to !important.

4 min read Level 3/5 #tailwind#layers#cascade
What you'll learn
  • Understand the base, components, and utilities layers
  • Add base resets and component styles to the right layer
  • Avoid specificity wars by relying on layer order

Tailwind sorts its CSS into native @layers. Layer order, not selector specificity, decides who wins — which is why a single utility class can override a complex component rule without !important.

The Three Layers

Tailwind defines them in this order: base, then components, then utilities. Later layers beat earlier ones regardless of specificity. So a .card rule in components is always overridable by a p-8 utility, even though both target the same element.

Adding to base

Use the base layer for element-level defaults and resets:

@import "tailwindcss";

@layer base {
  h1 {
    @apply text-3xl font-bold tracking-tight;
  }
  a {
    @apply text-blue-600 underline-offset-2;
  }
}

These set sensible defaults that any utility can later override on a specific element. In v4, the preflight reset and the default border-color already live in base.

Adding to components

Put reusable multi-property classes in components so utilities can still tweak them per instance:

@layer components {
  .card {
    @apply rounded-xl border bg-white p-6 shadow-sm;
  }
}
<div class="card p-10">Padding overridden, no !important needed</div>

p-10 is in the later utilities layer, so it wins over .card’s p-6 cleanly.

No More Specificity Wars

Because the cascade is decided by layer order, you stop reaching for !important and high-specificity selectors to force a style. Put each rule in the right layer and the override behaviour you expect simply happens — utilities on top, components in the middle, resets at the bottom.

theme() & Color Functions →