网页
综合
更新时间 2026-11-03 10:00:00
Modern CSS Might Make Your Front-End More Complex — Smashing Magazine
自动蜘蛛
www.smashingmagazine.com
正文约 6000 字
Gabriel is a front-end developer and technical writer. He specializes in HTML, CSS, JavaScript, React, Vue, TailwindCSS, and BootStrap, with a track record of … More about Gabriel ↬
Weekly tips on front-end & UX.Trusted by 182,000+ folks.
Have you ever replaced fifty lines of JavaScript with a few lines of CSS, merged the PR, and felt like you just did the codebase a favor? You replace ResizeObserver with a container query, the diff is mostly red, and everyone approves it before lunch.
This was what it looked like before you made the change:
See the Pen [demo (before PR) [forked]](https://codepen.io/smashingmag/pen/XJMxVJq) by Shoyombo Gabriel Ayomide.
Then, a week later, a card on the dashboard has vanished. A heading has grown on tablets for no reason anyone can explain. The spacing inside a comment is off.
See the Pen [demo (after PR) [forked]](https://codepen.io/smashingmag/pen/gbmBopp) by Shoyombo Gabriel Ayomide.
None of these bugs are in the few lines you wrote. All of them arrived with those few lines of CSS.
In my last article on how CSS is growing smarter, I left a few questions hanging at the end, including: What happens when logic is split between CSS and JavaScript, and how do we debug conditional styles without a clear view of what triggered them? This article is my attempt to answer these two questions.
I think it’s worth saying clearly that I am not saying modern CSS is bad. What I am saying is that:
A CSS feature can simplify a piece of code while making the wider application harder to reason about if you don’t understand how it relates to existing code, be it CSS or JavaScript.
Think of a new CSS feature as a new tenant moving into a shared apartment. The tenant may be quiet and tidy, but they still share a kitchen with everyone who already lives there. In that case, CSS is now roommates with JavaScript, the component’s layout, the CSS Cascade, and the browser’s rendering engine. The apartment’s stability depends less on the tenant and more on how they get along with one another.
That gives us two different things to measure, and a diff only shows the first one:
I am not the only one thinking about this. In April 2026, Igor Roztropiński published an essay titled “Modern Frontend Complexity: essential or accidental?” asking:
The essay landed on r/programming, where the thread has drawn 80-plus comments and the replies pull in two directions. One of the most upvoted comments, from a user named Kwantuum, pushes back on the whole genre:
Another commenter, kayinfire, takes the other side, arguing that “there are tons of scenarios where a front-end framework introduces more accidental complexity than it’s worth.” They say this a few replies later:
I think both commenters are on to something, and this article lives in the gap between the two. Yes, CSS has improved in the last several years. And yes, “less” CSS on paper is not automatically “less” complexity in practice. That said, my claim is narrower. A native feature only reduces complexity when it actually replaces what was there before and doesn’t disrupt the calm state of everything else it interacts with.
Let’s meet the housemates in our metaphorical apartment, one scenario at a time.
The first housemate is JavaScript, and the trouble starts when the old tenant never quite moves out. Here is a card that switches to a two-column layout when it has enough room. The original version uses a ResizeObserver to toggle a class:
With CSS Container Queries, we need no script at all and can simplify our selectors at the same time:
Lovely. Now, here’s the thing: migrations rarely happen in one clean sweep. The pull request adds the @container rule and removes the .card--wide .card__body rule. The observer survives because it is registered in another file. The .card--wide .card__title rule survives because nobody searched for the class. Nothing looks broken, because both implementations agree on 480px. Then a designer asks to move the breakpoint to 600px, and a developer updates the only place they know about: the @container rule.
See the Pen [Scenario 1: The Behaviour With Two Owners [forked]](https://codepen.io/smashingmag/pen/ZYeqvpx) by Shoyombo Gabriel Ayomide.
Between 480px and 600px, the card now has a single-column body and a wide-layout title. Nobody wrote that state. To find it, you need to know that the layout has two owners and read both of them.
The same trap comes in other shapes:
CSS and JavaScript can happily share a component. What they cannot share is the component’s behavior. So, instead of having a silent fight over a component’s behavior, check first. Know all the contending parties, then split the work.
And when you’re done migrating, you have to finish the job: delete the observer, the class, and every selector that mentions the class. Otherwise, you may wind up with a tenant who simply refuses to move out.
Back in 2023, I wrote about how block formatting contexts solve float issues. Back then, creating a block formatting context was something we did on purpose. Today, you can create one without meaning to. When we declare container-type: inline-size, we think we are saying, “let my children query my width.” The browser hears quite a bit more. This is the second housemate, the layout around the component, and our new tenant who just asked for one shelf has ended up rearranging the living room.
According to MDN’s container-type reference, the value “applies style and inline-size containment to the element.” And MDN’s guide to block formatting contexts lists “query containers (elements where container-type isn’t normal)” among the CSS styles that create one. An element that establishes a new block formatting context will, in MDN’s words:
That means one declaration can change three layout behaviors that have nothing to do with queries, plus a fourth that comes from inline-size containment. I built a demo where each “before” and “after” pair differs by only that one declaration.
See the Pen [Scenario 2: The Card Th
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。