Keeping CSS under control
Naming so classes do not collide, a reset so browsers agree, layers and nesting so specificity stops being a fight, and finding the rule that is actually winning.
By the end you can
- Name classes so two components never interfere with each other
- Start a project with a short, deliberate reset
- Use layers and nesting instead of escalating specificity
- Find the rule that is actually applying, in the browser
Easier if you did first
step 1 of 4
Naming so nothing collides
CSS has no folders. Every rule you write is live on every page at once, so a class called .title written for a card will also hit the .title in somebody's footer.
The usual answer is to name by component. The card's title is .card__title, not .title. Now it cannot possibly collide, because the name says where it belongs.
The common convention is called BEM: block, element, modifier. The block is the component, .card. An element inside it gets two underscores, .card__title. A variation gets two dashes, .card--featured.
It looks ugly the first time. What you get for it is that every class name tells you what it belongs to and where to find it, and you can delete a component and its styles with no fear of breaking something else.
The second half is keeping specificity flat. If every rule is a single class, every rule is equally strong, and the one you wrote last wins. The moment you write .page .sidebar .card h3 you have made a rule that can only be beaten by something even longer.
Rename the classes on the right so the component owns its names, with one modifier for the featured card.
.card { }
.card__title { } an element inside the block
.card__price { }
.card--featured { } a variation of the block
single class selectors, so nothing escalatesWhat these words mean
- block
- The component itself: .card.
- element
- A part inside it, written with two underscores: .card__title.
- modifier
- A variation, written with two dashes: .card--featured.
- flat specificity
- Every rule a single class, so none of them can out-rank another.
- utility class
- A tiny single-purpose class like .mt-4. A different approach, used by Tailwind.
Easy to get wrong
.card .title { }
.card__title { }
Two classes beat one, so this quietly out-ranks anything written with a single class later, and you have started an arms race with your own stylesheet.
Generic names like .title, .box, .blue
Names that say what they belong to
.title will be used again by somebody else on a page you have never opened, and then both components change at once.
What we check
- The card block is styled
- The title is named as part of the card
- So is the price
- The variation is a modifier
- No descendant selectors: every rule is a single class
- The price is bold through its own class