Key takeaways
- Replacing JavaScript with CSS often relocates complexity rather than removing it.
- Use modern CSS aggressively for layout and presentation, conservatively for behaviour.
- Discoverability and testability matter more than the smallest possible diff.
- Container queries and scroll-driven animations are near-universal wins; state logic is not.
- The goal is a codebase a stranger could understand in a year — not just shorter code today.
Every few months a new batch of CSS features lands in browsers, and the pitch is always the same: delete your JavaScript, let the platform do the work. Container queries, :has(), scroll-driven animations, nesting — the modern CSS toolkit is genuinely powerful. But there's a quieter truth that teams discover only after they ship: making a single component simpler can make the whole application harder to understand. The real question isn't can you replace JavaScript with CSS. It's whether the trade-off actually pays off for your product and your team.
The hidden cost of "less code"
When you swap a JavaScript event handler for a CSS-only solution, you're not removing logic — you're relocating it. A show/hide toggle built with :has() and a checkbox is elegant and dependency-free. But six months later, a developer debugging that interaction will look in the JavaScript, find nothing, and waste twenty minutes before realising the behaviour lives in a selector buried in a stylesheet.
This is the core tension Smashing Magazine's recent work on modern CSS surfaces: logic split between CSS and JavaScript increases the cognitive surface area of your codebase. Fewer lines, more places to look. For a solo project that's a non-issue. For a team of eight rotating across the codebase, it's a tax paid on every future change.
A framework for deciding
At Evocative we don't ask "is this the modern way?" We ask whether the complexity migrates or disappears. Use these questions before reaching for a CSS-only pattern:
- Does the logic belong to presentation? A hover reveal, a sticky header, a responsive layout shift — these are presentation. State that affects data, analytics, or business rules is not, and should stay in JavaScript.
- Can the behaviour be discovered? If a new developer can't predict where the logic lives, document it or reconsider. Discoverability beats elegance.
- Is it testable? JavaScript interactions are straightforward to cover with unit and integration tests. Pure-CSS behaviour often needs visual regression tooling you may not have.
- Does it degrade gracefully? Modern CSS features have uneven support. Know your fallback before you ship, not after a support ticket.
Where modern CSS clearly wins
Plenty of migrations are pure gain. Replacing a JavaScript resize listener with container queries removes real runtime cost and a whole class of bugs. Scroll-driven animations that previously required IntersectionObserver plumbing become declarative and performant. Layout that adapts without JavaScript is almost always more robust, because it survives when scripts fail to load. The rule of thumb: if the feature lets the browser do something it's natively optimised for, the complexity genuinely disappears rather than moving.
The parallel with AI in design

There's a striking echo here with the conversation happening across UX right now. Just as AI is reshaping the design process — automating the middle while reshaping where human judgement sits — modern CSS reshapes where front-end logic lives. In both cases the danger is the same: tools that reduce visible effort can quietly remove the context humans need to stay in control. "Human in the loop" in design means keeping people able to reason about the system. The front-end equivalent is keeping your team able to reason about the code. Convenience that erodes understanding is a long-term liability dressed up as a short-term win.
How we approach it at Evocative
Our rule is simple: adopt modern CSS aggressively for presentation and layout, conservatively for behaviour. We migrate in small, reversible steps, we document any non-obvious CSS-driven interaction directly in the component, and we treat browser support as a product decision, not a developer preference. The goal is never the smallest diff — it's the codebase a stranger could pick up in a year and understand without a map.
Modern CSS is one of the best things to happen to the front-end in a decade. But making your code shorter and making your product maintainable are not the same goal. The teams that win are the ones who know the difference before they refactor, not after.
Sources
- Synthetic users are making me rethink “imperfect research” — UX Collective
- AI is hollowing out the middle of design, leaving an hourglass behind — UX Collective
- Human in the loop means making sure the human is not out of the loop — UX Collective
- The AI reckoning in UX was 20 years in the making — UX Collective
- Modern CSS Might Make Your Front-End More Complex — Smashing Magazine