CSS Advanced: Variables, Motion and Modern CSS
Organising CSS at Scale
In this lesson you will
- Name classes consistently with BEM
- Control priority with cascade layers
- Use :where, :is and nesting to keep selectors simple
Introduction
A small stylesheet is easy. A stylesheet with 5,000 lines written by five people is where problems start: names clash, specificity wars break out, and nobody dares delete anything. A few habits keep CSS healthy as it grows.
Habit 1: consistent naming with BEM
BEM stands for Block, Element, Modifier. It is a naming pattern that makes a class name tell you what it belongs to.
- Block: a standalone component, such as
card. - Element: a part of the block, written
card__title. - Modifier: a variation, written
card--featured.
The names are a little long, but they keep selectors flat (one class each), so specificity stays low and predictable.
Quick quiz
In BEM, what is card__title?
Habit 2: cascade layers
@layer lets you decide the order of groups of rules. A rule in a later layer beats a rule in an earlier one, regardless of specificity. Declare the order once at the top:
Even though p.note is more specific than .text-red, the later layer wins. Note that styles written outside any layer beat layered styles.
Habit 3: keep specificity low
:where(...)takes the selectors inside it but adds zero specificity, so it is easy to override.:is(...)groups selectors, and counts as the most specific one inside.
HTML
:where(h1, h2, h3) { margin-block: 0.5em; } /* easy to override later */
:is(.card, .panel) a { color: inherit; } /* shorter than writing both */Habit 4: native nesting
CSS now supports nesting rules inside each other, with & referring to the parent. It is supported in current browsers.
Nest only one or two levels deep. Deep nesting makes selectors long and brittle.
Quick quiz
With cascade layers, which wins: a low-specificity rule in a later layer, or a high-specificity rule in an earlier layer?
Try it yourself
Add a new layer called overrides after components in the order list, and move the red text rule into it so that it still wins.
Summary
- Name things consistently, for example with BEM.
- Use
@layerto set the priority between groups of rules. - Keep specificity low with single classes,
:where()and:is(). - Nest sparingly, one or two levels deep.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading