
Tailwind: A Utility-First CSS Framework - Ethan_Mick
https://tailwindcss.com/docs/what-is-tailwind/
======
adamwathan
Author of Tailwind here! If you haven't worked with a library like this
before, I promise your gut reaction will be "holy hell this is the worst thing
I've ever seen" (it was my reaction too!)

You really do have to try it to shake that impression.

If you need a bit more convincing before you're willing to try it, I wrote an
in-depth article a while ago that documents my journey from a "semantic
classes"-loving HTML/CSS purist to a utility-loving heathen:

[https://adamwathan.me/css-utility-classes-and-separation-
of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

If you want to watch it in action, here's a screencast where I rebuild the
Netlify UI in an hour and a half without writing any custom CSS:

[https://www.youtube.com/watch?v=_JhTaENzfZQ](https://www.youtube.com/watch?v=_JhTaENzfZQ)

...and if you want "social proof", here's an interview I did with Diana
Mounter who leads the design systems team at GitHub about how moving to a
utility-based approach has made things infinitely more maintainable for them,
and given their developers a lot more confidence:

[http://www.fullstackradio.com/75](http://www.fullstackradio.com/75)

If you have any questions I'll be checking the comments, thanks!

~~~
tambourine_man
What if you need to change justification, image proportions, etc on mobile for
instance?

Also, from a previous comment of mine:

“Problem is, defining quantity in the class name doesn’t work. .m10 may be
fine for desktop but not for mobile. Then you’ll have media queries which
define .m10 as margin: 5px or something, which is nuts. You could go for
unspecified .mSmall etc, but in real life, things tend to be more specific and
messier, in my experience.”

[https://news.ycombinator.com/item?id=18083508](https://news.ycombinator.com/item?id=18083508)

~~~
mixmastamyk
Wouldn't using em units be a better idea in most cases?

~~~
edoceo
CSS has 'vh' and 'vw' units too, changed my life.

~~~
kaoD
'vmin' and 'vmax' too.

I'm experimenting with using 'em' and % everywhere, base font size with 'vmin'
and scaling font size with %. Works pretty well for scroll-less apps.

Example: [https://alvaro-cuesta.github.io/instant-trivia/](https://alvaro-
cuesta.github.io/instant-trivia/)

~~~
di4na
Hint : you can also use 'calc' with vw and vh to get some more complex
behaviours than purely proportional. You can add an offset, you can do some
multiplications etc.

Don't go overboard, but a little offset can go a long way

------
jasim
Tailwind is the best thing that has happened to CSS Frameworks in the last 10
years.

* Define the essence of your design in a JSON - typography, colors, spacings, shadows, borders et al.

* Anyone in the team including backend developers can create new interface components without waiting on a designer, thanks to well-defined scales that compose well.

* The component (HTML+CSS) is the unit of abstraction. eg: "ProfileCard". Inside ProfileCard you'll use Tailwind's utility classes to build your component. You reuse this component everywhere, and if you have to "change a button's padding across the product" (which to me is far too rare) you open your component files and change them there.

* It is so easy to build UIs - you don't have to name every single element in the DOM - these names are _only_ to act as "hooks" into the CSS, and serve no abstraction. With Utility classes you can just assemble them in the HTML without touching the CSS

* Tailwind has excellent documentation and great conventions - this means between projects all you need to know is their particular scale. Don't have to learn a new UI framework everytime.

* Consistency, consistency! Thanks to design scales.

* Works so well for custom UIs. Have your designer do absolutely original designs in Sketch, and first transcribe their scales into tailwind.config.js, and voila! start pushing out its HTML at breakneck speed.

~~~
mikewhy
I mean a lot of those things were possible with bootstrap-sass years ago.

> Define the essence of your design in a JSON - typography, colors, spacings,
> shadows, borders et al.

_variables.sass

> Anyone in the team including backend developers can create new interface
> components without waiting on a designer, thanks to well-defined scales that
> compose well.

This is true, but is solved by any sort of component system and not unique to
tailwind.

> The component (HTML+CSS) is the unit of abstraction. eg: "ProfileCard".
> Inside ProfileCard you'll use Tailwind's utility classes to build your
> component. You reuse this component everywhere, and if you have to "change a
> button's padding across the product" (which to me is far too rare) you open
> your component files and change them there.

Why would you change a padding in multiple files when you can set
`$base_padding: 10px`?

> It is so easy to build UIs - you don't have to name every single element in
> the DOM - these names are _only_ to act as "hooks" into the CSS, and serve
> no abstraction. With Utility classes you can just assemble them in the HTML
> without touching the CSS

Going by the first example in the linked article, something like "text-grey-
dark" seems like an awful idea when what it really means is "text-quiet". Heck
in their example "dark" is _lighter_ than the surrounding text.

~~~
jasim
_variables.sass works if you're using BEM. But now you have two component-like
things: BEM classes, and the components themselves. BEM solves the issues
inherent in nested CSS (cascade, inheritance, multiple selectors, specificity)
by forcing us to never nest them, and instead having to name every single
element in HTML. Though they look semantic, they are not truly reusable since
they are coupled deeply with the markup. But with Tailwind, your component is
your unit of abstraction and you don't have to name everything just for the
sake of hooking up the HTML with CSS.

But you can even do BEM with Tailwind if you really want to with @apply.

> Why would you change a padding in multiple files when you can set
> `$base_padding: 10px`?

Neatly written CSS that uses variables for design scales are a good thing to
have, but without any kind of tooling help, it is really difficult to keep it
consistent. Tailwind on the other hand gives you the affordance for that - a
"pit of success" because you never have to define magic values and instead use
pre-defined functional CSS classes.

Regarding colors - you can use "text-quiet" or "text-title" etc. - the names
are fully in your control and can be set in the configuration JSON file.

~~~
e12e
BEM?

~~~
Raphmedia
BEM — Block Element Modifier is a methodology that helps you to create
reusable components and code sharing in front-end development

[http://getbem.com/introduction/](http://getbem.com/introduction/)

In short, you do things like this:

.form { }

.form--theme-xmas { }

.form--simple { }

.form__input { }

.form__submit { }

.form__submit--disabled { }

Where the prefix __ is an Element and -- is a Modifier.

So, in that example you have the form, the form with Christmas modifier and
also a form button that is expected to only happen under forms.

------
edhelas
I personally have an issue with this "Utility/Functional" CSS pattern.

To me I still think that the good old "HTML describe how the content is
organized, CSS describe how this content looks like" is the way to go. In the
end it's how CSS and HTML were designed at first.

But when I see that

    
    
       <div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden"></div>
    

I'm sorry but it just doesn't feels right to me.

~~~
badestrand
Yes, the problem is that this library just replaced typing

    
    
        <div style="background: white">
    

with

    
    
        <div class="bg-white">
    

without realizing that the first is considered a bad practice for a reason and
that the second is equivalent.

~~~
aloisdg
Isn't that basically the same thing as inline styles?

Not quite, for a few reasons:

Inline styles don't respect media queries, which basically rules out
responsive design

Inline styles aren't limited to pre-defined options, meaning you can still end
up with 90 different shades of blue)

Inline styles cause specificity issues, since they trump separate stylesheets.

Inline styles don't support print-specific styles.

Inline styles can't address pseudo-elements (such as ::before and ::after)

Inline styles can't apply to multiple elements. Utility classes can define
.bg-blue once and have it apply to many things, which leads to shorter markup
and quicker rendering speed.

Inline styles are a pain to type. Compare class="f-sm bg-blue" to style="font-
size: 10px; background-color: #0000ff;".

Utility classes fix all of these things.

from [https://www.mikecr.it/ramblings/functional-
css/](https://www.mikecr.it/ramblings/functional-css/)

~~~
josephmx
So what happens when your design changes and suddenly all your white buttons
need to be off-grey? You change the class on 700 components?

~~~
sebdedeyne
There seems to be a misconception that you need to go all-in on utilities when
using a framework like Tailwind.

If you have 500 buttons using the exact same set of classes, you should of had
a button class in the first place. Almost all my projects have their own
button and form input classes for this exact reason!

Where utility-based CSS frameworks really start to shine is the other 75% of
your codebase, where you're inventing clever class names, only to end up using
them once.

This is also why Tailwind calls itself a utility-FIRST framework. Build things
with utilities, and extract components to classes when the need arises.
Avoiding early abstractions provides a lot of value (in any programming
language for that matter). Not having to invent a name for every single piece
of UI also saves a ton of headaches down the road.

~~~
josephmx
That does make a lot more sense!

------
mcgwiz
All CSS "frameworks" should be thought of as utility libraries, including
Bootstrap. If you apply the framework classes directly to your HTML, you've
tightly-coupled your HTML (which is already tightly-coupled to your
information architecture) to an implementation detail of your presentation
code.

Most frameworks support some kind of re-use of CSS declaration blocks - use
that feature to build your components from the primitives they provide, but
also add a layer of indirection by putting those components behind a semantic
class name. Voila, loose-coupling with all the productivity benefits of the
frameworks.

    
    
        <button class="login-button">Login</button>
    
        .login-button { @apply .btn-primary; }
    
        .btn-primary { @apply .font-bold .py-2 .px-4 .rounded; }

~~~
zumu
This is imho the correct approach.

All the benefits with none of the coupling. Tailwind might actually be pretty
nice if used this way.

------
fideloper
I DEFINITELY recommend trying this out before you decide utility CSS isn't for
you.

The practical dev workflow of using tailwind is a breath of fresh air.

Coming back to old projects with bespoke CSS is SO PAINFUL to edit/change
compared to something built in Tailwind.

You absolutely also have the power to make css components/abstractions as
well.

------
mstg
People please don't judge without giving it a try. Just signed up to write
that Tailwind truly changed the way I work. Centralized configuration for
styles, colors etc.

Tailwind is the only CSS framework I use since I discovered it and I'm
gradually converting my/company projects to use it.

------
benfrain
I tried the utility approach many years ago and while I can see the appeal in
some situations I think it’s far from a panacea. My journey led to me writing
[http://ECSS.io](http://ECSS.io) The opposite way of tackling CSS at scale.
Instead of abstraction I opted for isolation.

------
maouida
Recently I had to do some updates on a UI that used tailwind framework. It was
the most unpleasant experience I have ever had. I quickly got eye strain
looking at all those attributes.

Keep HTML for HTML and CSS for CSS.

------
blairanderson
Hi There, have you tried Tachyons?

[https://github.com/tachyons-css/tachyons](https://github.com/tachyons-
css/tachyons)

Its similar, but has been around since 2015.

~~~
dmix
Also [http://basscss.com/](http://basscss.com/) which convinced me of the
genius of using this functional/utility approach to CSS.

The website themes just seemed so much simpler and minimalist, but also more
consistent across the whole site. Significantly reducing the amount of time I
need to create my own CSS classes.

------
sanbor
It is convenient but you are not separating markup and presentation. I think
the whole point of css is to swap stylesheets and get a different
presentation, like demostrated by
[http://www.csszengarden.com/](http://www.csszengarden.com/) BEM/OOCSS lets
you do this.

~~~
ssijak
How many times you do that in real project? Or have you ever done that in your
career? And if a project needs substantial redesign it is usually acompanied
by the functionality change, which means you need defferent html/components
too, so you still can`t just swap css files.

~~~
rverrips
+1 on this for "real projects" that actually do use different styles. Our
enterprise e-commerce platform uses an internally maintained design system
with utility classes only, very similar to tailwindcss. We have 15 different
"brands", so simply reference a different "brand" to get it's unique styling,
while the utility classes all remain the same.

~~~
carapace
I think a lot of folks underestimate just how much can be done with this
approach.

"Steel" [http://www.csszengarden.com/219/](http://www.csszengarden.com/219/)

------
petemill
I do see the 'utility'(!) of this kind of approach to css, but have a main
issue on responsiveness. Yes, the solution commonly touted is to define global
breakpoints: 'small' 'large', etc. But for me defining those globally is too
narrow. Sometimes different groups of components need to respond differently,
with context. More worryingly, soon we'll move to 'element' queries, which
should suit better than screen-based media queries. We'll be able to say 'when
this component is squeezed down to < 500px wide, then wrap the second element
underneath the first. That approach is more compatible with modern component
architecture. But I don't see a context-specific or even component-specific
solution immediately with this framework.

------
thinkxl
I like Tailwind. I think the appeal here is to write less CSS, get things done
faster, have a consistent design and the maintainability. All good so far.

But let's remind everybody that this is only one approach of many you can use.

One approach that can solve problems Tailwind tries to is proper planning. An
initial style guide can show you that the `author-bio` component looks similar
to `article-preview` (taken from the author's blog post[1]), so you beforehand
plan for that HTML and CSS and create a component you can reuse.

Of course, you could have decisions made after the fact and go back and change
stuff; nothing is bulletproof.

\- [1] [https://adamwathan.me/css-utility-classes-and-separation-
of-...](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/)

------
bennofs
An important difference in my mind is between designing a web application vs
designing a web document.

In the document case, it is possible to mostly keep the document semantic and
apply styling via CSS. It matches the content/style separation well.

For web applications, I really like tailwind-like approaches, for multiple
reasons:

* changing the style globally is probably hard anyway without adapting the HTML as well (as in the app case, often lots of other things depend on margins etc for example and you have a lot less uniformity/more special cases than in the document case)

* because there is less uniformity, the reuse aspect of the traditional content/presentation split is greatly reduced anyway

* web apps often use component based frameworks already, so you still get reusable components

------
albedoa
The big thing that Tailwind brings to functional CSS is the emphasis on and
mechanisms for composing from utility classes.

This is something that went understated in other functional libraries, even
though composition has been possible for years using preprocessors. So when
people saw Tachyons, for instance, they would recoil at what they saw as an
unmaintainable mess even though the underlying theory is sound.

I really like the work Adam is doing and where he is leading the conversation.
I will read anything he writes, too. He's great at expressing his ideas and
rallying you around things you didn't know you care about.

------
redonkulus
How is tailwind different than Atomic CSS? [https://acss.io](https://acss.io)

Small utility classes without writing CSS, seems like the same thing.

Disclaimer: I worked with the devs that created it.

~~~
NO_CHANGE
From adamwathan's article, Tailwind's advantage is it limits you to fewer
choices. So .text-grey .text-grey-dark .text-grey-darker .text-grey-darkest...
rather than coming up with and remembering the hex color values, which might
vary between team members.

------
pssflops
Wow, the letter spacing and intuitive responsive design is very impressive.
While I can't quite yet abandon bootstrap, this looks like a great
alternative.

------
flats
We switched over from a Bourbon-based SASS framework at my work to Tailwind
several months ago & it has been fantastic. I was very negative about it at
first - “isn’t this just a crappier version of inline styles?” - but I’m a
convert. It’s customizable, it enforces consistency, and it dramatically
reduces the amount of CSS you have to write, which is a good thing on several
levels. Give it a try.

------
k__
_" Separation of concerns" is a straw man_

So true.

That's why CSS-in-JS is awesome.

Everything is in one component, nobody cares anymore if you need to edit
markup AND styles.

~~~
dsego
Although you lose theming. Unless you provide a way to inherit the component
and override the default styles.

------
aarondf
I've been using Tailwind for about a year, and it has really put the joy back
into using CSS for me. I know that's crazy to say, but I used to always have
_so_ much trouble figuring out what to name things and popping back and forth
between HTML and CSS. It was super frustrating, and now I can just flyyyy
while building out frontend.

------
robmerki
Please give Tailwind a try before knocking it. The syntax seems strange, but
after 15 minutes you'll be in love. It doesn't work for every project, but
it's a great tool to have in your arsenal. I've been following Adam and Steve
on Twitter for quite some time, and these guys are total pros.

------
jimbo1qaz
I can only imagine the lack of semantic classes makes it almost impossible for
end-users to reliably restyle the page using Stylus userstyles. I'd say this
type of CSS is hurting power users.

------
ssijak
Btw, nothing is preventing you from combining Tailwind with your other methods
of writing CSS. For example you could write CSS Grids for general layout and
use Tailwind for styling components.

------
platz
I started a side project with tachyons.io, but it seems i probably should've
gone with tailwind.

Really i don't need the compile-step, just really wanted to get out of the
bootstrap canton

------
giancarlostoro
Would be nice to see sample templates of what it all looks like in practice.

~~~
tnorthcutt
[https://tailwindcomponents.com/](https://tailwindcomponents.com/)

~~~
giancarlostoro
Thanks! That page has odd behaviors on mobile at least on Android with
FireFox. But it looks like the css has clean looking components.

------
uhoh-itsmaciek
What's the difference between tailwind and tachyons?

~~~
platz
You can generate tachyons from tailwind

~~~
uhoh-itsmaciek
Okay now I get it. That's neat. I'm using tachyons but this approach is
compelling.

For what it's worth, I don't think "What is Tailwind?" makes that clear (the
"designed to be customized" section hints at it) and I had to read
[https://tailwindcss.com/docs/configuration](https://tailwindcss.com/docs/configuration)
to understand the difference after reading your comment. Thanks!

------
interfixus
> _< div class="bg-white ...">_

Are we missing a [1996] in the title?

------
andrewmcwatters
One of the biggest strengths of Bootstrap is that everyone uses Bootstrap. I
can come to a company, use Bootstrap, and expect that new employees will also
use Bootstrap or that it's already been used there! It's so common in the
industry.

It also means, for front-end developers like me, that I can create a company
theme on Bootstrap, and get junior developers to use it can feel comfortable
with being able to implement the brand design language and not have to pixel-
fiddle. Not only does this strengthen the technical skillset of my team, but
it also helps keep standards high when dealing with offshore resources.

We can get them to build UI for entirely separate projects, slap our branding
on it, and dramatically cut down on resource allocation, time, and effort.

So, here's the thing: this is great, but Bootstrap also has utility classes
these days. If I use Tailwind, or Foundation, or Bulma, I immediate lose out
on developer leverage. This is so much more powerful than moving some classes
around.

Approaching all of these design concerns in a slightly different way just
isn't powerful enough to outweigh the leverage Bootstrap has over everything
else out there.

It's just not significantly different enough. It doesn't standout to me. In
fact, how it differentiates in its introduction is a _con_ to me. No, the
industry doesn't need complete UI kits, design languages vary enough that this
could provide additional undesired weight, however people use buttons, drop-
downs, and many other common components _all the time_.

A major competitor to Bootstrap in the arena would need to do something
revolutionary.

~~~
cramer_corey
You make interesting points. For me, as a back-end developer, the prevalence
of Bootstrap is a major con because I can't (due to lack of knowledge or
confidence, I'm not sure) make a Bootstrap site look like anything other than
a Bootstrap site with different colors. Tailwind is the first front-end
framework that successfully got me away from that and helped me execute own
unique design vision. What seems to come to you easily is a complete struggle
for me.

~~~
janimo
For websites where having a unique design is not a requirement or a priority,
Bootstrap and similar frameworks are very helpful.

~~~
cramer_corey
Don't disagree with this at all. Bootstrap, like Tailwind, is a tool and after
I purchased a cordless drill I didn't go around telling everybody I know to
throw out their manual screwdrivers because the revolution has arrived. It
seems to me that's what people perceive is happening here.

------
gcb0
"it doesn't have a default theme" ...One paragraph later "here's a business
card in the default theme"

technically, it have all the themes to the point that picking up individual
color for everything make it as unmaintanable.

------
JohnH42
"bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden"

5 years ago, it should had help some dudes but right now ... choose
foundation/bootstrap/materialcss ... or build your own BEMized css ...

