Lisa Tassone

How TailwindCSS helps you implement a design system (and why it can be better than CSS-in-JS solutions)

As a programmer who has held design and user experience roles, I appreciate the process and value those disciplines add to a product and the companies that make them a priority. I’ve worked at organisations that treat design and UX as an after-thought. Functionality trumps all. While this approach gets you so far (you may release a feature into the market before anyone else for example), there comes a point where you lose customers because a competitor simply makes it so much easier to do the same thing you do - through great design.

Throughout my career, I have noticed that there is often a gap in collaboration and communication between Design and Engineering - even at companies that value both. This gap naturally leads to issues in efficiency, consistency and a lack of understanding around each role’s goals and challenges.

Common pain points between Engineering and Design teams

All of these things make working as a developer less fun and I encountered them all when I started working on a React application a couple of years ago. It was particularly tiresome creating so much custom CSS, working in a maze of it and not having any documentation around the approach or what was currently built. It was also frustrating getting inconsistent designs that made it hard to re-use anything I had previously created.

If I change this line or remove this property, what am I going to break? Any developer who’s worked with CSS at scale

I really wanted to find a way to make my life easier and improve the collaboration between the design and engineering teams; speak the same language to deliver the product we all had a hand in making. What we needed was a design system. Not just a sketch file that the design team used. But an approach to unify how designers created their designs and how engineers implemented them.

What is a design system?

For me a design system is the way you produce a product and get it into the hands of your customers. It’s all encompassing. When most people explain what a design system is though, at least in the software industry, it usually goes something like this:

Design systems are a collection of rules, constraints, and principles implemented in design and code. Sylvee L

Because my main pain point with this project was dealing with the CSS, I started to look at ways to make it suck less.

The goals:

CSS-in-JS solutions

Styled components was starting to get talked about more as devs expressed their issues over “running out of names to call things”; “writing basically the same CSS but it needs to be just a bit different”; “the CSS is so specific, I have to write even more specific code to apply my change”; “what can I re-use if anything?”

Benefits

Drawbacks

Utility CSS as a solution

It was about this time that I started looking at utility CSS with more discerning eyes. I had heard of this approach before but like any developer who first sees something like this:

<p class="f6 ttu b fl w-100">
  <strong class="red bg-white">Hi! I'm styled with utility classes!</strong>
</p>

There was a strong reaction of the negative kind.

This is just inline styling! Those class names are nasty! Most developers (minus or plus additional sass - pun intended)

It’s not inline styling by the way. You don’t have the specificity or the problem of re-use you have with inline styling.

I came across a talk by Simon Swiss and then articles by Adam Wathan and Sarah Dayan that all articulated my experience with CSS at scale and found utility CSS to be not only faster to use but a natural evolution to working with CSS in large projects. I highly recommend checking them out; they have done a great job explaining the arguments around the topic.

With most utility CSS frameworks, you define what your project will use such as measure units, colours and shadows for example, and it will generate individual CSS classes for everything you need to build your UI. Design teams can then add the class names to their tools and designs which is crucial for consistency across teams.

Apart from those things, why consider a utility CSS approach and how might it be better than implementing a CSS-in-JS solution?

Utility classes expose a well-defined API that you can use to compose more complex components. You’re not re-writing styles; instead, you’re relying on classes that define styles and behaviours once and for all. Sarah Dayan

Benefits

Drawbacks

Why TailwindCSS?

Selling it

All of this discovery and thinking lead me to present a spike (a quick protoype of how something could work) using TailwindCSS within our project and explaining the benefits of utility-first CSS. I was able to delete close to 600 lines of custom CSS refactoring one component pattern!

In combination with being able to provide a common language to use between the design and engineering teams, it was full steam ahead using TailwindCSS as the foundation of our design system. Storybook was set up to document our React components that were now built with a utility-first approach. Designers updated their Sketch files to be in sync with what developers were using to implement the designs. We were achieving the goals I had set out to reach.

Each project has to take into account it’s own requirements, but the next time you find yourself lost in a spaghetti bowl of CSS, perhaps try out utility CSS as a starter.