A tangled web of wires labelled with different CSS approaches.

We Keep Reinventing CSS, but Styling Was Never the Problem

Den Odell

Den Odell 6 August 2025 · ⏱️ 3 min read

We’ve been building for the web for decades. CSS has had time to grow up, and in many ways, it has. We’ve got scoped styles, design tokens, cascade layers, even utility-first frameworks that promise to eliminate bikeshedding entirely.

And yet, somehow, every new project still begins with a shrug and the same old question:
“So… how are we styling things this time?”

It’s not that we lack options. It’s that every option comes with trade-offs. None of them quite fit.
We keep reinventing CSS as if it’s the root cause.
It isn’t.


CSS Wasn’t Made for This

It’s easy to forget what CSS was originally designed for: documents. You’d write some HTML, style a few headings and paragraphs, maybe float an image to the left, and call it a day. In that world, global styles made sense. The cascade was helpful. Inheritance was elegant.

Fast-forward a couple of decades and we’re building highly interactive, component-based, state-driven, design-system-heavy applications, still with a language meant to style a résumé in the early 2000s.

CSS wasn’t built for encapsulated components. It wasn’t built for dynamic theming or runtime configuration or hydration mismatches. So we’ve spent years bolting on strategies to make it work.

Every Option Solves One Problem. None Solve All of Them.

What we have now is a landscape of trade-offs.

  • BEM gives you naming predictability, and very verbose selectors.
  • CSS Modules give you scoping, unless you need runtime theming.
  • Utility-first CSS (like Tailwind) enables fast iteration, but clutters your markup.
  • CSS-in-JS offers colocation and flexibility, at the cost of runtime performance and complexity.
  • Cascade Layers and :where() give you more control, if your team is ready to learn them.

Each approach solves something. None solve everything. Yet we keep framing them as silver bullets, not as trade-off tools.

Maybe It’s Not CSS That’s the Problem

Here’s the uncomfortable truth: most of our styling pain doesn’t come from CSS itself.
It comes from trying to shoehorn CSS into frontend architectures that weren’t designed to support it.

React, Vue, Svelte. They all put components at the core. Scoped logic. Scoped templates. Scoped state. Then we hand them a stylesheet that’s global, cascading, and inherited by default.

We’ve spent the last decade asking CSS to behave like a module system. It isn’t one.

The Real Question: Which Pain Are You Willing to Accept?

This isn’t just a tooling choice.
It’s a question of what trade-offs you’re prepared to live with.

Do you want:

  • Scoped styles with minimal tooling? Use CSS Modules and accept limited runtime flexibility.
  • Predictability and no cascade? Use utility-first CSS and brace for cluttered markup.
  • Dynamic styles colocated with logic? Use CSS-in-JS and monitor your bundle size closely.

There’s no single solution. Just strategies. Just context.

Accept the Mess. Choose With Your Eyes Open.

Styling the web isn’t solved. It may never be. But it gets easier when we stop pretending there’s a perfect answer just one abstraction away.

Be clear about what matters, and deliberate about what you’re willing to trade.

Because at the end of the day, no one writes perfect CSS.
Just CSS that’s good enough to ship.


💬 Comments? Join the discussion on Dev.to →

🔗 Share: Twitter/X · LinkedIn ·


Related Posts

  • Table-based layout structures
    Hacking Layout Before CSS Even Existed 11 June 2025

    The early web had no layout system. No CSS. So we improvised, slicing, stretching, and nesting our way to structure.

    Read more →

  • Developer facing off against a robot against a screen of code.
    AI Is Just the Latest Frontend Killer. Don’t Panic. 9 July 2025

    Apparently, frontend developers are about to be made obsolete. This all sounds very familiar.

    Read more →

  • Enjoyed this? Get more like it to your inbox.

    No spam. Just occasional deep dives on frontend engineering and developer experience.