Problem space

Adam Wathan wrote an article recently called CSS Utility Classes and “Separation of Concerns”. In it, he documents his journey through different ways of thinking about CSS. A lot of it is really familiar.

Phase 1: “Semantic” CSS

Ah, yes! If you’ve been in the game for a while then this will be familiar to you. The days when we used to strive to keep our class names to a minimum and use names that described the content. But, as Adam points out:

My markup wasn’t concerned with styling decisions, but my CSS was very concerned with my markup structure.

Phase 2: Decoupling styles from structure

This is the work pioneered by Nicole with OOCSS, and followed later by methodologies like BEM and SMACSS.

This felt like a huge improvement to me. My markup was still “semantic” and didn’t contain any styling decisions, and now my CSS felt decoupled from my markup structure, with the added bonus of avoiding unnecessary selector specificity.

Amen!

But then Adam talks about the issues when you have two visually similar components that are semantically very different. He shows a few possible solutions and asks this excellent question:

For the project you’re working on, what would be more valuable: restyleable HTML, or reusable CSS?

For many projects reusable CSS is the goal. But not all projects. On the Code For America project, the HTML needed to be as clean as possible, even if that meant more brittle CSS.

Phase 3: Content-agnostic CSS components

Naming things is hard:

The more a component does, or the more specific a component is, the harder it is to reuse.

Adam offers some good advice on naming things for maximum reusability. It’s all good stuff, and this would be the point at which I would stop. At this point there’s a nice balance between reusability, readability, and semantic meaning.

But Adam goes further…

Phase 4: Content-agnostic components + utility classes

Okay. The occasional utility class (for alignment and clearing) can be very handy. This is definitely the point to stop though, right?

Phase 5: Utility-first CSS

Oh God, no!

Once this clicked for me, it wasn’t long before I had built out a whole suite of utility classes for common visual tweaks I needed, things like:

  • Text sizes, colors, and weights
  • Border colors, widths, and positions
  • Background colors
  • Flexbox utilities
  • Padding and margin helpers

If one drink feels good, then ten drinks must be better, right?

At this point there is no benefit to even having an external stylesheet. You may as well use inline styles. Ah, but Adam has anticipated this and counters with this difference between inline styles and having utility classes for everything:

You can’t just pick any value want; you have to choose from a curated list.

Right. But that isn’t a technical solution, it’s a cultural one. You could just as easily have a curated list of allowed inline style properties and values. If you are in an environment where people won’t simply create a new utility class every time they want to style something, then you are also in an environment where people won’t create new inline style combinations every time they want to style something.

I think Adam has hit on something important here, but it’s not about utility classes. His suggestion of “utility-first CSS” will only work if the vocabulary is strictly adhered to. For that to work, everyone touching the code needs to understand the system and respect the boundaries of it. That understanding and respect is far, far more important than any particular way of structuring HTML and CSS. No technical solution can replace that sort of agreement …not even slapping !important on every declaration to make them immutable.

I very much appreciate the efforts that people have put into coming up with great naming systems and methodologies, even the ones I don’t necessarily agree with. They’re all aiming to make that overlap of HTML and CSS less painful. But the really hard problem is where people overlap.

Have you published a response to this? :

Responses

Kevin Marks

This is interesting when read with the "don’t style microformats" intuition. We seem to be at stage 2 or 3 with them.

# Posted by Kevin Marks on Tuesday, August 29th, 2017 at 1:47pm

Related posts

Speaking at Web Day Out

Have you got the perfect talk for this event? Let me know!

Announcing Web Day Out

A one-day event all about what you can in web browsers today: Brighton, March 12th, 2026. Tickets are just £225+VAT!

Making the website for Research By The Sea

Having fun with view transitions and scroll-driven animations.

Manual ’till it hurts

Try writing your HTML in HTML, your CSS in CSS, and your JavaScript in JavaScript.

Displaying HTML web components

You might want to use `display: contents` …maybe.

Related links

Why I’m Writing Pure HTML & CSS in 2025

  • Building HTML pages is easy
  • Pure HTML is evergreen
  • Bloated web pages are too slow
  • I can host it anywhere, often for free
  • Accessibility and SEO benefits are automatic
  • It won’t need security patches
  • There are no build steps

Tagged with

I’m more proud of these 128 kilobytes than anything I’ve built since | by Mike Hall | Jul, 2025 | Medium

I don’t normally link to articles on Medium—I respect you too much—and I do wish this were written on Mike Hall’s own site, but this is just too good not to share.

And don’t dismiss this as a nostalgiac case study from the past:

At no point did the constraints make the product feel compromised. Users on modern devices got a smooth experience and instant feedback, while those on older devices got fast, reliable functionality. Users on feature phones got the same core experience without the bells and whistles.

The constraints forced us to solve problems in ways we wouldn’t have considered otherwise. Without those constraints, we could have just thrown bytes at the problem, but with them every feature had to justify itself. Core functionality had to work everywhere, and without JavaScript crutches proper markup became essential.

This experience changed how I approach design problems. Constraints aren’t a straitjacket, keeping us from doing our best work; they are the foundation that makes innovation possible. When you have to work within severe limitations, you find elegant solutions that scale beyond those limitations.

Tagged with

Kelp

A UI library for people who love HTML, powered by modern CSS and Web Components.

Tagged with

Close to the metal: web design and the browser

It seems like the misguided perception of needing to use complex tools and frameworks to build a website comes from a thinking that web browsers are inherently limited. When, in fact, browsers have evolved to a tremendous degree

Tagged with

Matthias Ott – Painting With the Web – beyond tellerrand Düsseldorf 20025 - YouTube

A great talk by Matthias on what you can do with web standards today!

Tagged with

Previously on this day

12 years ago I wrote August in America, day twenty-six

Chicago, Illinois.

15 years ago I wrote Listening

Listen to this.

17 years ago I wrote hCard Wizard

Matthew Levine is an overlord of the Lazy Web.

23 years ago I wrote www.thegirlinthepicture.com

This is too cute. Not only is this an online marriage proposal, it’s a great little quicktime movie too.

23 years ago I wrote Evolutionism Propaganda

Here’s an hilarious rant from a creationist nutcase claiming that Apple are not only pushing an "Evolutionist" agenda but that they’re godless commies to boot:

23 years ago I wrote Meteorite hits girl

What are the odds?