I spent a year loving to hate Tailwind CSS so you don't have to.
I've finally released my Figma Community file of all the Tailwind CSS primitives as design tokens and variables so designers have the resources they need to work with teams developing "class-first".
The Tailwind CSS challenge
If you’ve ever told another designer you are on a team building with Tailwind CSS and had them say, “I’m so sorry,” you know what I’m talking about.
Tailwind is… weird.
Their tagline is “build anything,” they tend to promote to engineers that they don’t need designers. 🙀
Tailwind CSS has a unique way of writing front-end code with a “class-first approach,” which often leads to designers working with engineers feeling trapped in “primitives land.”
Here’s my story about how I grew to love to hate Tailwind. This led me on a mission to get some designer-friendly resources into the community to help others avoid the frustrating experience I went through.
🔗 Get your copy of my free Figma community file for Tailwind CSS primitives
My rocky introduction to Tailwind CSS
The first time I worked on a team building with Tailwind, there was a bit of a battle.
I’m used to working with semantic names to express my design decisions as tokens, but my engineers were not having it.
No matter how much I documented and tried to over-communicate, things just weren’t getting built as I designed them.
The engineers told me they were building with Tailwind CSS and were briefly glancing at my designs for “inspiration” and then would build something good enough using compatible components they could “pull in from code.”
So basically, they wouldn’t even look at my tokens or docs anymore because they were useless to them. 😭
I wanted to help bridge this gap between design and engineering, so I went looking for a Figma component library for Tailwind that I could use.
I honestly thought “Tailwind” was the name of the component library that used CSS, like Radix or Ant Design.
Tailwind’s official Figma community file hadn’t been updated in over a year. There was a note that it wouldn’t be supported by them anymore. The other community files I found only had primitives in them, which were named weirdly, and I couldn’t find components at all.
I was so confused.
Landing on Tailwind’s website, I noticed they were hosting an event two weeks later, about an hour's drive from where I live in Toronto, so I decided to buy a ticket and go learn everything I could.
Thankfully, I found some awesome designers and engineers in the Tokens Studio community Slack channels who were also working with Tailwind.
They quickly helped me realize that Tailwind is not a component library that uses CSS but a specific way of writing CSS.
Tailwind CSS… 🤦♀️ Now I get it!
So what makes it so special?
CSS vs Tailwind CSS
The Tailwind CSS website says, “Utility-first Fundamentals. Building complex components from a constrained set of primitive utilities”.
This “utility-first” approach is the reason why I was struggling so hard with my engineers.
A “utility” in Tailwind refers to a “utility class.”
A class
in CSS is a label attached to an HTML element that provides styling information and rules.
CSS classes are traditionally flexible and fully customizable.
Tailwind CSS is a collection of pre-defined utility-classes that engineers can pull from instead of writing their own classes from scratch. They claim this speeds up and simplifies the development process.
That doesn’t sound so bad…
However, looking at the Tailwind CSS class names, they match what designers typically call a “primitive option” in their design system, like a color named blue-500.
Now, the statement “Building complex components from a constrained set of primitive utilities” on their website makes a lot of sense.
So, when I was taking my
blue-500
token
and giving it an alias of
brand-color-default
then referencing it as the value of my
button-brand-tier1-hover-bg-color
token,
the engineers I was working with couldn’t make sense of it!
My tokens have moved past the primitive Tailwind CSS class names they were used to using. 🤯
Tailwind’s utility-first approach doesn’t mean utility-only
At the Tailwind event, I talked to as many engineers as I could. To my surprise, none of them had ever heard of design tokens… but were intrigued by the idea. 😬
During one of the presentations, the speaker claimed, “This is why you don’t need designers anymore; you can build anything class-first,” and everyone cheered.
I was shocked 😢
Later in the evening, I gathered the courage to ask one of the speakers if Tailwind was going to support design tokens, and he said, “We don’t really need them, so not likely.”
I also explained my current struggle with the team I was working on being stuck in “primitives land,” his response was encouraging.
What I learned from him is that the “utility-first” approach can sometimes be interpreted as “I can’t use semantic names; I can only use the (primitive) class names,” however, “utility-first” doesn’t mean “utility-only.”
While it's true that Tailwind uses specific primitive utility classes like blue-500
, they claim that you can “Build anything with Tailwind CSS” because you can fully customize it.
This tailwind.config.js
config file allows engineers to define custom class names which could support moving out of “primitives land” and into “semantic territory” if we want to use design tokens.
Brilliant!
However, just cuz they can doesn’t mean they will. Or, they might not even know it’s possible.
Turns out, the reason they were hosting events like this was to help engineers learn about how to customize Tailwind so they could build anything… without a designer (or tokens). 😳
My Figma community file of Tailwind CSS primitives
So, while I can’t deliver you a Tailwind component library in Figma, I’ve put everything a designer needs to “build anything” while they are stuck in “primitives land” in this community file.
It has all the Tailwind CSS primitives as design tokens powered by Tokens Studio, which are attached to Variables in Figma.
The names of the tokens and variables match the Tailwind CSS class names.
When you use the primitives in your designs, the engineers inspecting your work will see names that match what they have access to in code.
I’ve also added a ton of resources and links to help designers learn the quirks of Tailwind CSS so they feel confident having conversations with engineers about how their designs are being built.
There are also resources to blogs, guides, and docs which explain how to customize the Tailwind config files to support semantic naming.
The goal is to have enough information to have productive and informed conversations between designers and engineers so they can come up with a collaborative way to scale design systems built with Tailwind CSS that helps them get out of “primitives land” and into “semantic territory.”
🔗 Get your copy of my free Figma community file for Tailwind CSS primitives
If you want to customize the file with your own font family, update the living docs, or add to the file, I’ve linked to the guides previously published here on my substack and YouTube in the Figma file.
I knew this massive file was coming and wanted to be sure the community had the tips and tricks to customize it ahead of its release, which is why last month’s newsletter recaps them all in one place.
I hope you found this helpful! Feel free to reach out if you have questions or want to share about your own journey working with Tailwind.
p.s. I’m so sorry….