``` CSS-in-JS:前端理智的巨大背叛 ```
CSS-in-JS: The Great Betrayal of Front End Sanity

原始链接: https://thenewstack.io/css-in-js-the-great-betrayal-of-frontend-sanity/

CSS-in-JS 最初承诺解决诸如全局命名空间冲突和特异性问题等样式挑战,提供组件级别的样式。然而,它在很大程度上未能实现这一目标,反而引入了新的问题,例如运行时性能瓶颈、难以阅读的代码以及复杂的调试——尤其是在水合不匹配的情况下。 它没有简化样式,而是将 CSS 生成与 JavaScript 绑定,造成了性能开销,并抵消了分离表示和逻辑的原始好处。关于性能影响可以忽略不计的说法存在争议,审计显示网络和运行时成本增加,尤其会影响低端设备的用户。 虽然最初因开发者体验而受到赞扬,但 CSS-in-JS 往往会导致架构债务和规模化时的复杂性增加。幸运的是,一场转变正在发生,Remix 和 Next.js 等框架提倡使用传统的 CSS、CSS Modules 和静态提取。现代 CSS 功能,如变量和容器查询,现在可以以原生和高效的方式解决 CSS-in-JS 旨在解决的原始问题,证明浏览器内置的样式引擎仍然优越。未来在于拥抱简单并尊重既定的 Web 标准。

一场 Hacker News 的讨论围绕着一篇批评 CSS-in-JS 的文章展开。尽管最初被宣传为解决全局命名空间冲突等样式问题,但评论员认为它并未兑现承诺——作用域已经解决了这些问题。一些开发者欣赏 Emotion 等库提供的开发者体验 (DX),允许灵活的样式选项,尽管存在性能缺陷和 SSR 兼容性问题。 然而,一个关键的争论点在于发布内容的质量,指责存在“LLM 垃圾”——文章严重依赖于 AI 生成的文本,缺乏原创性。 许多评论员对作者将 AI 撰写的内容冒充为自己的作品表示不满,破坏了作者和读者之间预期的付出交换。 最后,讨论指出,许多现代 CSS-in-JS 是*编译*的,而不是在运行时计算的,这使得一些批评已经过时。有人提出了关于 HTML 中作用域样式的未来,指出潜在的不一致性和被忽视的规范。
相关文章

原文

We were promised elegance. What we got was runtime CSS parsing, unreadable class names, and hydration bugs straight out of hell. CSS-in-JS was supposed to free us from global namespace nightmares and styling spaghetti.

Instead, it wrapped us in a shiny new layer of chaos — one that performs worse, reads worse, and somehow costs more CPU cycles to do what a plain stylesheet did perfectly fine two decades ago. This is not evolution; I’d call it over-engineering disguised as progress.

From Liberation to Performance Lock-In

When CSS-in-JS first appeared, it felt revolutionary. No more global leaks, no more worrying about specificity wars, no more cryptic class collisions. We could co-locate styles with components, making everything modular and “self-contained.”

But the honeymoon ended quickly. Quickly, developers realized that generating styles at runtime wasn’t a small tradeoff — it was a ticking performance bomb. What started as a way to simplify styling turned into one of the most expensive abstractions ever introduced into frontend development.

By tying CSS generation to JavaScript execution, we effectively welded presentation to logic — the exact thing we were trying to avoid when we invented CSS in the first place.

The idea of dynamically computing CSS on the client side sounds clever, until you’re debugging a hydration mismatch at 3 a.m. because some SSR pass decided to hash class names differently between the server and browser. It’s the kind of issue that feels less like a bug and more like a punishment for trusting marketing copy. CSS-in-JS libraries made the simple act of styling a button as complex as dependency injection. And let’s not even start on how much bundle size ballooned just to make borders blue.

By tying CSS generation to JavaScript execution, we effectively welded presentation to logic — the exact thing we were trying to avoid when we invented CSS in the first place. The elegance of separation was replaced with inline chaos wrapped in hooks and context providers.

The Hidden Performance Tax of Convenience

Developers often defend CSS-in-JS with the argument that “the overhead is negligible.” It’s not. Runtime styling introduces measurable performance degradation — from the milliseconds lost parsing strings, to the memory overhead of style recalculations. Anything involving commerce in digital form is at risk.

Every time a component mounts, the system has to create, inject, and sometimes even deduplicate style tags. Multiply that across hundreds of components, and you’ve turned your render cycle into a bureaucratic mess.

What was once the web’s biggest advantage — lightweight rendering — is now being sabotaged by overzealous abstraction.

This is not hypothetical. Performance audits consistently show that CSS-in-JS frameworks add both network and runtime costs. You might not notice it on your 16-core dev machine, but your users on low-end devices certainly do. What was once the web’s biggest advantage — lightweight rendering — is now being sabotaged by overzealous abstraction.

The tragedy here is that the browser already has a battle-tested, optimized system for handling styles: CSS. We replaced it with a JavaScript imitation that’s slower, harder to debug, and occasionally decides to vanish on page refresh. CSS-in-JS didn’t make styling faster: it just made debugging slower.

And yet, the cycle continues. Framework maintainers build patch after patch, trying to make dynamic styles “feel native.” But you can’t out-optimize the browser’s own styling engine. It’s like rebuilding a wheel inside a wheel — except this one leaks memory and needs an npm update every week.

The Developer Experience (DX) Mirage

Advocates often claim CSS-in-JS improves developer experience. They’re right — until you actually have to maintain it. At first glance, it feels modern and ergonomic. Styles live in your component file. Scoped classes feel clean. Variables are accessible.

But once the codebase scales, the illusion collapses. You start hunting for missing prop interpolations, juggling context providers and rewriting logic — all because your styles can’t handle simple overrides without rewriting half the component tree.

Debugging CSS-in-JS feels like playing Minesweeper with class hashes. DevTools turns into a cryptic wasteland of obfuscated selectors. Inspect an element and you’ll find something like .css-4kq0lj{margin:0 auto} — not exactly readable. Good luck tracing that back to its source when you have a dozen styled components inheriting from each other like a dysfunctional family tree.

This obsession with “DX” — developer experience — has become a smokescreen for architectural debt.

Worse, CSS-in-JS encourages overengineering. Why write a simple media query when you can import a hook and toggle the theme context dynamically? Developers who once debated whether to use Flexbox now debate which flavor of runtime styling performs 2% better on hydration. The mental load is immense. The payoff? Marginal at best.

This obsession with “DX” — developer experience — has become a smokescreen for architectural debt. Sure, it feels nice to import styled-components and write CSS in backticks. But that dopamine hit fades quickly when your app’s performance tanks and your build times double. Convenience is not craftsmanship. And CSS-in-JS is convenient at the expense of clarity.

The Return to Sanity: A Post-CSS-in-JS Future

Thankfully, the tide is turning. Even the most die-hard CSS-in-JS proponents are starting to admit it’s unsustainable at scale. Frameworks like Remix, Astro and Next.js 13 are nudging developers back toward simplicity — leveraging traditional CSS, CSS Modules, or static extraction instead of runtime generation. The message is clear: separation of concerns still matters.

The rise of CSS variables and container queries, as well as scoped styles, means modern CSS now handles most of what CSS-in-JS tried to fix — but natively, efficiently and predictably. No runtime penalties. No hash collisions. No invisible style tags clogging your DOM. Just styles that load instantly and behave consistently.

CSS is not broken; our discipline is.

We don’t need to reinvent styling. We just need to respect the boundaries that made the web work in the first place. CSS is not broken; our discipline is. The answer isn’t more abstraction — it’s better understanding. The future isn’t about embedding CSS into JavaScript, but about writing maintainable styles that scale naturally with the web’s evolution.

Returning to fundamentals is simply maturity and a normal shift towards practicality. It’s realizing that adding layers of abstraction to solve problems we created ourselves is not innovation. It’s just pure denial.

Modern CSS Solves the Original Problem

CSS-in-JS was born out of good intentions — modularity, predictability and componentization. But what we got was complexity disguised as progress. The web didn’t need runtime styling engines or cryptic hashes to stay modern. It needed restraint. It needed developers willing to accept that not every problem requires a library.

We’re entering a new chapter where simplicity is sophistication again, where global stylesheets coexist peacefully with scoped rules. Where the browser does the heavy lifting, as it was always meant to, it’s time to stop worshipping abstractions that slow us down and start trusting the platform we’ve spent decades improving. Ready to make the move?

Group Created with Sketch.
联系我们 contact @ memedata.com