Writing CSS that works is easy. Writing CSS that's still easy to change six months from now — once a project has grown past a handful of pages — is the actual skill. This post pulls together the habits that separate a stylesheet that stays manageable from one that slowly turns into a tangle nobody wants to touch.

Use a Consistent Naming Convention

Pick a naming system and stick to it across the whole project. One of the most widely used is BEM (Block, Element, Modifier), which names classes so their relationship is obvious just by reading them:

<div class="card card--featured">
  <h3 class="card__title">Title</h3>
  <p class="card__description">Description text</p>
</div>

card is the block, card__title is an element that belongs to it (double underscore), and card--featured is a modifier — a variant of the block (double dash). You don't have to use BEM specifically, but having some agreed convention means any developer can guess how a new class should be named without asking.

Avoid Overly Specific Selectors

/* Brittle — breaks the moment the markup structure changes slightly */
div.sidebar ul li a.nav-link {
  color: blue;
}

/* Resilient — targets the one class that actually matters */
.nav-link {
  color: blue;
}

Deeply nested, overly specific selectors are fragile: move the markup around even slightly and the rule stops matching. They also make specificity conflicts harder to reason about later, since a highly specific rule is difficult to override cleanly without an equally specific (or more specific) selector somewhere else.

Centralize Repeated Values with Variables

:root {
  --primary-color: #2563eb;
  --spacing-unit: 8px;
  --radius: 6px;
}

Any color, spacing value, or radius used more than two or three times across a project belongs in a CSS custom property, not hardcoded repeatedly. The payoff shows up the first time a client asks to change the brand color and it's a one-line edit instead of a project-wide find-and-replace.

Organize Rules Logically

Group related styles together and keep a predictable order within each rule — for example: positioning, box model (display, width, padding, margin), typography, then visual details (color, background, border). Splitting a large stylesheet into separate files by component (or by section, for a single-page site) also makes it far easier to find the one rule you need to change, rather than scrolling through one 3,000-line file.

Avoid !important

/* A warning sign, not a solution */
.btn {
  background: red !important;
}

!important overrides the normal cascade entirely, which usually means it's patching over a specificity problem rather than fixing it. Once one !important exists, the next developer who needs to override that rule often reaches for another !important to beat it — and the stylesheet spirals from there. Reaching for a more targeted selector, or restructuring the CSS so the rule you want naturally comes later in the cascade, almost always produces more maintainable code.

The Common Thread

Every practice above solves the same underlying problem: making a change in one place should only affect what you actually intended to change. Consistent naming, low specificity, shared variables, logical organization, and skipping !important all push toward that same goal — CSS that stays predictable as a project grows, instead of CSS that only the person who wrote it can safely touch.