CSS Design System

August 2019

Here is a little success story from the trenches about, essentially, writing some CSS. If there is a lesson to the story, it would be not to over engineer code.

A bit of background

About a year ago I joined a team working on a large frontend application. The project had been going for about three years, and many engineers with little direction meant the code was a bit of a mess. The framework was AngularJS.

Long story short, I decided to focus my attention on the set of common UI components that were used in the project. They were overly complicated, difficult to use, and next to impossible to update. Originally they had just been Google’s Material Design components; but by the time I joined, they had morphed into a bastardized version with little consistency or structure.

Worse: other teams on different projects (within the company) also used them.

To take one example, the table component could sort and filter its rows based on some parameters. It could also do pagination and expand rows to show more info. It could even fetch its own data. Complete with loading and error states, and a retry button.

It could do all that (when stars aligned), but it had its problems.

Other components were not much better.

“Let’s just do the CSS”

I do not make a decision to completely rewrite something lightly, but this was not just a case of rewriting. I wanted something different. For everybody. I wanted a set of components that were

  1. Simple to use and understand for users. Simplicity and purpose are key words here. It should be crystal clear what a certain element is for and how to use it.
  2. Accessible Accessibility is helping everybody and it generally helps keeping the design focused and on point.
  3. A language for other designers A small, but powerful, set of components with which designers could “express” most (not 100%) of what they needed.
  4. Developer friendly Great documentation. Extensible. No assumptions about tech or use. Simple.

I have a lot to say about these points, but underlying it all, is the understanding that complexity ruins it for everyone. Sure it helps the screen reader that a table is actually a <table>; but it also helps the accountant (a power user) who has to paste numbers into Excel; and it even helps the developer, because tables are a basic building block of the web, making it almost trivial to implement.

I found one designer who understood what I wanted to do, and together we went to work. He produced the basic raw components in Invision, and I coded them up in CSS with only the BEM naming convension to keep the CSS from becoming an entangled mess. It was a very tight process, with short cycles, constant (but short) meetings and follow-up questions. It worked because we were few people that trusted each other to do good work, and because we both knew a good deal about the other’s domain (I about design, he about HTML and CSS).

Why not SASS? That’s the question I get most often.

  1. SASS encourages complexity. You can make soft rules about what to use and what not to use, but you have to communicate these rules to others, and be ruthless in enforcing them. CSS bypasses this.
  2. CSS is easier to read for someone dropping by to do a quick PR, than SASS is.
  3. CSS is less code. CSS is only the code that you write. It’s very possible to accidentally create an explosion of code in SASS.
  4. CSS is SASS. It is easy to change from CSS to SASS in the future. Going the other way is less easy.
  5. SASS is a program. It needs installing, updating, etc. This is not the most difficult thing in the world, but it’s another dependency that I have to manage from behind a firewall. I’d rather not.

I will upgrade my tool when I need it; but not one day earlier. Take heed my friend.

To be fair, I had a compilation step to concatinate the files and to replace, var(--main-bg-color) with whatever that variable was set to. We have to support IE11 for now, but not forever, so at some point, we can remove that. Having a separate file for each component allowed us to publish each file individually for those teams that prefer to have their components co-exist with the CSS.

I also created a catalog of all the components, complete with handles to show or hide error states, toggle on or off disabled states, fill in labels so you can see what happens when they overflow, etc. A <pre> displays the HTML code as it changes (for the curious, this was done in HyperApp). It is hard to know for sure, but I believe this has been instrumental to the success of the project.


With the help of anther team promoting the project, I can honestly say that the project has wildly exceeded my expectations. I am contacted daily by people in teams I don’t know of with questions, suggestions, and pull requests.

One big learning for me, was that we found that teams prefer to keep the control and build the JavaScript components themselves. We initially wanted to wrap the CSS in some components of different frameworks, but some teams straight up declined using ours in favor of just making their own.

This hit home in a big way, when one day I changed focus to investigating possible approaches for migrating to something other than AngularJS. What that has meant, practically, has been to make a lot of prototypes. And I’ve been blown away at how quickly I can create the basic components in different frameworks and languages. Copy/paste the html from the catalog and hook it up with some logic. It has really been that simple.


Even in a total rewrite, this CSS is the only part that will survive unscathed. Not the business logic, not the translations, not the templates, not the login system. Nothing but this file of CSS. This rock solid, small file of CSS.