CSS Best Practices
CSS at small scale is forgiving; at the scale of a real, growing application, sloppy conventions compound into specificity wars and styles nobody's confident is safe to remove.
Last updated 2026-09-08
Avoid deep selector nesting and overly specific selectors
A selector like .page .content .sidebar ul li a is fragile (breaks if markup structure changes) and hard to override cleanly later. Flatter, class-based selectors are more maintainable and predictable.
Use a consistent naming convention (BEM, utility-first, or CSS Modules)
Without a consistent convention, class names collide or become ambiguous as a project grows, and it becomes unclear which styles are safe to change without checking every usage.
Prefer relative units (rem, em, %) over fixed pixels for typography and spacing
rem-based sizing respects a user's browser font-size preference (relevant for accessibility), and scales more predictably across a design system than hardcoded pixel values everywhere.
Avoid !important except as a genuine last resort
!important overrides normal cascade rules, and once used, the only way to override it again is another !important — a pattern that compounds into a specificity arms race that's hard to reason about.
Use CSS custom properties (variables) for repeated values
Hardcoding the same color or spacing value across dozens of rules makes a later design change require finding and updating every occurrence. A custom property changes everywhere from one place.
Common Mistakes to Avoid
- ⚠Deep, fragile selector chains that break the moment markup structure changes slightly
- ⚠Reaching for !important instead of fixing the underlying specificity issue
- ⚠Hardcoded pixel values scattered everywhere instead of a shared spacing/color scale
- ⚠No consistent naming convention, leading to ambiguous or colliding class names
- ⚠Styling based on element type/tag rather than class, causing unintended styles elsewhere
Frequently Asked Questions
Is utility-first CSS (like Tailwind) a best practice or an anti-pattern?
Neither inherently — it's a legitimate, popular approach with real tradeoffs (verbose markup, less semantic class names) traded for speed and consistency. The 'best practice' framing depends more on team preference and project needs than either approach being objectively correct.
Should I always use CSS-in-JS?
It's one legitimate option among several (traditional stylesheets, CSS Modules, utility frameworks), each with different tradeoffs around runtime cost, tooling, and team familiarity — no single approach is universally 'best'.