CSS Cascade Layers: Ending Specificity Wars with @layer
When two CSS rules conflict, specificity usually decides who wins. That leads to !important and ever-longer selectors. Cascade layers add a level above specificity: rules in a later layer beat rules in an earlier layer, no matter how specific.
Declare the order once
@layer reset, vendor, base, components, utilities;
Put styles into layers
@layer reset {
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }
}
@layer components {
.button { padding: 0.5rem 1rem; background: var(--brand); }
}
@layer utilities {
.hidden { display: none; }
}
.hidden wins over any component rule because utilities comes last, even against a high-specificity selector like #app .toolbar .button.
Taming third-party CSS
@import url("datepicker.css") layer(vendor);
Now your base and components layers override the vendor styles without fighting their specificity.
Rules to remember
- Styles not in any layer beat all layered styles.
- Inside one layer, normal specificity and order apply.
!importantreverses layer order: an important rule in an early layer beats one in a later layer.- Tailwind CSS v4 and many design systems use layers internally, so your unlayered CSS overrides them easily.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.