~/TechPurAI
~/tutorials/css-from-scratch/css-architecture-organizing-a-real-stylesheet
intermediate·part 20 of 22·4 min read

CSS architecture: organizing a real stylesheet at scale

Updated Aug 16, 2026CSS

Every part so far has added real rules to what's implicitly become one growing stylesheet. This part covers how to organize that real file (or split it into several) so it stays maintainable well past the point where a single flat list of rules starts becoming genuinely hard to navigate.

A real, practical file structure

text
styles/
├── tokens.css        → part 5's real custom properties (colors, spacing, type)
├── reset.css         → box-sizing, margin resets, real baseline normalization
├── base.css          → real, unclassed element styles (body, headings, links)
├── layout.css        → part 9-13's real header, grid, positioning rules
├── components/
│   ├── product-card.css
│   ├── forms.css
│   └── buttons.css
└── main.css           → imports every file above, in a real, deliberate order
css
/* main.css */
@import url("tokens.css");
@import url("reset.css");
@import url("base.css");
@import url("layout.css");
@import url("components/product-card.css");
@import url("components/forms.css");
@import url("components/buttons.css");

This real order isn't arbitrary — tokens have to load before anything that references them with var(); the reset and base layers establish real, foundational defaults before more specific component rules override them; component files come last, since they're generally the most specific, targeted rules in the whole real stylesheet.

Why it matters

@import inside CSS has a genuine, real performance cost worth knowing about — each imported file is fetched sequentially by the browser rather than in parallel, which can measurably slow down real page load compared to linking multiple stylesheets directly from HTML, or using a real build step to concatenate them into one file before deployment. The file-splitting shown above is valuable for real, human organization during development; how those files actually get delivered to a real production browser is a separate, genuine decision covered in part 22's deployment coverage.

Avoiding real specificity wars

css
/* the real trap: escalating specificity to win a conflict */
.product-card .price { color: #555; }
.sale .product-card .price { color: red; }
#homepage .sale .product-card .price { color: red !important; }
text
The real, better alternative: flat, class-based selectors with a
  deliberate naming convention, avoiding deep nesting entirely
.price { color: #555; }
.price--sale { color: red; }

This directly extends part 3's specificity coverage into a real, practical architectural principle: deeply nested selectors chasing a real specificity fight are a genuine, common sign the underlying approach needs rethinking, not more nesting. A flat, single-class-per-rule approach (part 2's .price--sale modifier pattern) sidesteps the entire real problem — every selector has roughly equal, low specificity, so later rules in the cascade reliably win through source order alone, exactly the predictable behavior part 3 covered as the simpler, real case.

When BEM (or a similar convention) genuinely pays off

css
.product-card { }
.product-card__title { }
.product-card__price { }
.product-card--featured { }
.product-card--out-of-stock { }

Introduced briefly in part 2, BEM's real value compounds specifically as a stylesheet grows — a class name like .product-card__price is immediately, unambiguously scoped to its real component, with zero risk of accidentally colliding with an unrelated .price class defined for something else entirely elsewhere in a large real stylesheet. For Bright Leaf Coffee's site at this series' current real scale, it's a genuinely optional nicety; for a larger real site with dozens of components built by more than one person, it becomes a genuinely load-bearing convention that prevents real, hard-to-trace naming collisions.

Real comments that explain why, not what

css
/* wrong: restates what the code already says */
.product-card {
  display: flex; /* makes it flex */
}

/* correct: explains a real, non-obvious reason */
.product-card {
  /* min-height keeps cards visually aligned even when one product's
     title wraps to two lines and another's doesn't */
  min-height: 320px;
}

A real, well-chosen comment explains a genuine constraint or decision that isn't obvious from the code alone — a comment restating what a property already says in plain English adds real, ongoing maintenance cost (it has to be kept in sync with the code) with zero real informational benefit.

A real, honest measure of good architecture

text
The genuine, practical test: can a real change to one component's
  styling be made confidently, without needing to check whether it
  will unexpectedly affect something unrelated elsewhere on the page?

Every principle in this part — token-based values, flat specificity, clear naming, purposeful file organization — serves this one real, practical goal. A stylesheet that passes this test reliably is genuinely well-architected, regardless of which specific convention or file structure was used to get there.

Next: common CSS mistakes — a direct, honest roundup of the real failure patterns this series has flagged individually, brought together in one place.

VK

Vijay Kumar

Founder of TechPurAI — writing hands-on tutorials and honest tool breakdowns.

LinkedIn ↗
← previous19. Dark mode: real prefers-color-scheme support done properlynext →21. Common CSS mistakes