Keys to maintainable CSS: Order

Sort to save your soul

CSS is a second class citizen in software, designed only to style and present content: Developers tend to (and love to) be annoyed by it.

CSS has a stain, it has quirks and implementation details that change over time. It's growing up slowly, the working group is hard to follow, and new functionality takes time to be up to date with.

It's a hassle, I love it.

In this series, I'll collect tips'n things that could make a difference.


There is always a reason CSS gets messy, but let's not jump the shark yet, start with the basics: Order. A familiar syntax, you know the class, it does what it does, this code will render a button.

This is how most a lot people write CSS.

.button {
    color: white;
    background: #3f55aa;
    border-radius: 0.5rem;
    border: 1px solid white;
    font-size: 1rem;
    margin: 1rem 0;
    display: inline-flex;
    transition: opacity 100ms ease;
    padding: 0 0.5rem;
    font-family: sans-serif;
    text-transform: uppercase;
    position: relative;
    z-index: 99900001;
}

When I see something like this, here is what I think: Sigh. A button. And this is what I'd like to know instead: Where is it, what it does, how it looks, and can I safely modify it?

Is this sustainable? Can this waterfall approach scale in any way? Absolutely not. OK then, let's pretend we care and order properties from a-z.

.button {
    background: #3f55aa;
    border-radius: 0.5rem;
    border: 1px solid white;
    color: white;
    display: inline-flex;
    font-family: sans-serif;
    font-size: 1rem;
    margin: 1rem 0;
    padding: 0 0.5rem;
    position: relative;
    text-transform: uppercase;
    transition: opacity 100ms ease;
    z-index: 99900001;
}`

Is this better? It feels better, scales better, but without further structuring it's still a mess.

I found the following practice to be the closest to how design works. Hint: Yes, it was design all along.

.button {
    position: relative;
    z-index: 99900001;

    display: inline-flex;
    margin: 1rem 0;
    padding: 0 0.5rem;

    background: #3f55aa;
    border-radius: 0.5rem;
    border: 1px solid white;
    color: white;
    transition: opacity 100ms ease;

    font-family: sans-serif;
    font-size: 1rem;
    text-transform: uppercase;
}

Now we're talking. From a quick glance, you:

  • know this element is relatively positioned
  • have the explicit line to put a new property
  • can remove that margin property that doesn't belong here

It's accessible.

The order is the following:

  • Layout: The position of the element in space. Eg.: `position`, `top`, `z-index`.
  • Box: The element itself. Eg.: `display`, `overflow`, `box-sizing`.
  • Visual: Design of the element. Eg.: `color`, `border`, `background`.
  • Type: Typesetting of the element. Eg.: `font-family`, `text-transform`.

Picking up this simple system is easy, and it's a step that could save you from drowning in product debt. Now, please go ahead and at me (@pyx) asking where to put that `--webkit` prefix you must include manually.


Edit: Adding some actual resources to go with the theory. My approach initially came from exporting and grouping design assets; influenced by the principles of idiomatic CSS.

Others: