#Frontend

Why “CSS is hard” is a misreading of the problem, not the language

AI & ML Reporter
4 min read

Julia Evans explains that CSS’s difficulty stems from the complexity of layout, not from any inherent flaw in the language. Understanding the historical solutions and the nuances of “centering” shows that mastering CSS is about learning a rich, well‑engineered system rather than fighting a broken tool.

What’s claimed

Julia Evans, in a recent personal essay, pushes back against the mantra “CSS is hard.” She argues that the frustration many developers feel comes from misunderstanding what CSS is trying to solve—layout—rather than from any fundamental shortcoming of the language itself. By taking CSS seriously, learning its long‑standing features, and abandoning the reflex to dismiss it, she says her experience with web development changed dramatically.

What’s actually new

The claim isn’t that CSS has suddenly become easier; it’s that the community’s narrative around it is stale. Over the past decade, the CSS specification has added a suite of layout modules that directly address the pain points developers used to label “impossible”:

Problem Historical workaround Modern CSS solution
Horizontal centering of block elements margin: 0 auto; with fixed width display: flex; justify-content: center;
Vertical centering Table‑cell hacks or absolute positioning with transforms display: grid; place-items: center;
Responsive two‑column layouts Floats + clearfix grid-template-columns: 1fr 1fr;
Complex nesting without extra markup Nested tables or extra wrapper divs CSS custom properties + calc()

These modules—Flexbox (2012), CSS Grid (2017), and newer additions like aspect-ratio (2021) and container queries (2023)—were all part of the standards process long before most developers started treating them as optional tricks. What Evans highlights is the knowledge gap: many developers still default to Tailwind or utility‑first frameworks because they hide the underlying spec, not because the spec is unusable.

A concrete example: centering

The phrase “centering is impossible” appears in countless beginner tutorials. The reality is more nuanced:

  1. What does “center” mean?
    • Center a single inline element within a line?
    • Center a block element horizontally within its containing block?
    • Center both axes within a viewport?
  2. Which layout mode is active?
    • Block layout respects margin: auto.
    • Flex layout uses justify-content and align-items.
    • Grid layout uses place-items or place-self.
  3. What constraints exist?
    • Fixed width vs. intrinsic size.
    • Minimum/maximum sizing (min-width, max-width).
    • Overflow handling.

When you map the problem to the appropriate layout model, the solution is a one‑liner. The difficulty is in choosing the right model, not in the language lacking a feature.

Limitations and remaining friction

Even with a mature spec, a few practical issues persist:

  • Browser implementation lag – While modern browsers support Flexbox and Grid fully, older versions (IE11, early Edge) still require fallbacks. Projects that need to support legacy environments must keep polyfills or duplicated CSS paths.
  • Tooling gaps – IDE autocompletion for newer properties (container-type, subgrid) is still catching up. This can make discovery feel harder than it is.
  • Design‑system inertia – Large codebases often lock in older patterns (float‑based grids, clearfix hacks). Refactoring to modern layout modules is non‑trivial and can introduce regressions.
  • Learning curve for composability – Understanding how custom properties, calc(), and clamp() interact with layout modules adds a mental load. It’s not that CSS is broken; it’s that the language is expressive enough to be misused.

Practical takeaways

  1. Audit your existing CSS – Identify patterns that could be replaced with Flexbox or Grid. Tools like CSS Stats can surface over‑use of floats or excessive specificity.
  2. Pick a layout model per component – If a component only needs simple horizontal alignment, Flexbox is usually the lightest choice. For two‑dimensional layouts, Grid gives you explicit row/column control.
  3. Embrace native features before utilities – Before reaching for a utility‑first framework, ask whether a native property solves the problem. This reduces bundle size and keeps the stylesheet readable.
  4. Stay current with the spec – Follow the CSS Working Group’s drafts or the MDN changelog. New properties (e.g., aspect-ratio, container queries) often address recurring UI patterns.
  5. Document intent, not implementation – When you write display: grid; place-items: center;, comment that the goal is centered content rather than grid layout, making future maintenance easier.

Conclusion

Julia Evans’s reflection is less a defense of CSS and more a call to treat it as a fully fledged programming interface. The language’s difficulty mirrors the inherent difficulty of layout on the web, not a lack of engineering. By learning the historical context of features like Flexbox and Grid, and by aligning the problem statement with the appropriate CSS module, developers can move past the “CSS is hard” mantra and start using the language as the powerful, standards‑driven tool it was designed to be.


References

Comments

Loading comments...