Once you get over the small learning curve, it gets to be VERY productive. Think of it as writing CSS at a slightly higher level of abstraction. That abstraction being in not having to edit two separate files or areas of your HTML document (unless you want to abstract further with @apply).
Not having to go through the 'define identifier in element, then define in StyleSheet' workflow. With Tailwind you get the most commonly used style definitions pre-defined. But not so high level that it LOOKS pre-defined. Giving you room to customize greatly. How could it not be faster?
I recently completed a theme in Tailwind, mostly to get the hang of it: https://planflow.dev/free-themes/. And managed to go from idea to finished theme in about 4-5 days. That's the fastest I've ever done it.
Thanks for the heads up!
Keeping your CSS and HTML completely separate just doesn't work in practice though e.g. we still need to throw in ad-hoc wrapper `div`s because CSS isn't powerful enough to do what we want, we have to pollute the HTML with class names that have little semantic relevance outside of styling as we're creating the styling, and it's a pipe dream that designers can jump in and help with the styling without help from the programmers.
It's a nice idea but keeping HTML and CSS 100% separate hasn't panned out - people need to accept that and stop promoting the separation of CSS and HTML dogmatically. The reason there's so many CSS frameworks and different ways to do the same thing on the frontend is a strong evidence we're still figuring out the best way to do things. CSS has been out for around 20 years now and it still doesn't do what we need it to.
Also, if you're keeping your data (like blog posts, product information) in a database, your data is already separate from your UI/styling. What are you gaining by splitting up your styling further? Is a similar level of splitting up done in other (non-HTML) UI frameworks?
(1) You have to think less. Try "margin-top medium", look at the result, "oh it's too much", try "margin-top small", look at the result, ok fine. No px-fiddling.
(2) It produces more consistent results (i.e.: things tend to look nicer).
What doesn't win me is that, while I see the increase in development speed this brings, I don't see how would you handle maintainability (i.e.: what happens when the design needs to change?). I suspect the trade-off here is that you just renounce to such redesigns and commit to the idea that you'll rebuild the entire thing if/when the time comes (tech advances so quickly in this space that you may want to do it anyway).
margin-top: margins(xl);
- Once you are in the "margin-top: xxx" part, nothing prevents you from saying "just this time" and writing some px (or whatever) value, either because you don't remember the options at your disposal, because none of them feel exactly right or whatever. Using tailwind you would have to create an entirely new size definition, which is a big hassle. That is, using scss does not actively push you to this particular "pit of success" whereas using tailwind does.
- Responsive handling is much more verbose in scss. Consider "sm:mt-2" versus "@include responsive(sm) { margin-top: margins(2) }"
Spacing, button styling, border radius, shadows, font sizing - basically the things its easy to get wrong - are already decided for you so its easy to make something that looks decent pretty instantly.
I have also been using Tailwind Builder[1] which is pretty helpful for learning Tailwind and also generating things like menus and basic page layouts pretty quickly.
But the web environment has changed. React and Vue introduced modularity of style and structure with components. So I can just use a Button component across the website instead of a CSS class. This means CSS is mostly written only for that specific component or file. So tailwind and those other css-in-js have sprung up to bring both into one file.
And I’ve been using tailwind for about a year now and can very quickly throw together most layouts. It feels very smooth to be able to define the div and it’s style on one line at the same time. And short classnames like “m-4” and “w-full” are also more succinct than the raw html style property.
It also works perfectly fine with server-rendered pages in my experience. Any templating engine worth its salt will allow you to extract fragments or partials.
BUT! This proves there isn’t a “right” way to do things and developers have differing preferences—enough to make 7 figures of revenue.
I think everybody reacts like this at first (including me) :) If you put styles directly in the attribute, nothing is preventing your from using a color that's not part of your palette, nor using sizes that do not respect your UI "flow". Tailwind comes with a (customizable at build time) well-defined sets of colors and sizes.
I recommend watching the 17-minutes long talk "In Defense of Utility-First CSS" for those curious about Utility-First CSS: https://www.youtube.com/watch?v=R50q4NES6Iw
This may be the stated point, but it breaks down in many cases. Tailwind, Tachyons, etc. are often a more straightforward, maintainable approach.
One main benefit is to constrain the actual power of CSS specificity.
The other main benefit is that these micro-styles map closely to design semantics, not functional semantics. This is covered in the OP. At a certain scale, the number of distinct functional semantics grows huge, but the design semantics remain bounded.
IMHO it is really quite similar to using HTML attributes for styling or inline styles. Maybe those wheren't actually such terrible ideas. They are the easiest thing for a beginner to understand, so maybe they are actually the easiest way to reason about styles for non-beginngers too.
What makes it different is: - higher level component frameworks: wether you use react, vue, web components or use a templating engine in a component pattern, that is all the abstraction you need. Introducing an additional layer of abstraction/reuse with shared CSS classes is uneccessary overhead. - constraints: the scales for spacing, color, typography and everything else that you configure for tailwind lead to nice, consistent designs without much effort. I think that would be a key problem when just using inline styles.
You get 1 class apply to many nodes relationship.
You only write the css once more (or never again if you use tailwind or tachyons) and reuse it many times.
More thoughtful reply to similar question from Adam Morse of tachyons: https://github.com/tachyons-css/tachyons/issues/12#issuecomm...
bg:white is exactly the problem. What if I want to change all my white backgrounds to #FCFCFC? I've got the option of going through and updating all my components individually or updating bg:white to be a non-white value.
It's part of the selling point, that config file becomes your design system. They provide a decent one but you are free to overhaul it as you see fit. It works really well.
Read the docs for a few minutes and try it out, you may come to different conclusions than your current assumptions.
Positioning, sizing and styling is very easy, especially when you can control all those aspects with variables in your view classes.
You have to try it to understand it.
<div style="padding: 20px;" />
and <div class="p-2"/>
it's like variables for styling. Instead of throwing some random numbers developers can bump the numbers up p-3, p-4 or text-red-200, text-red-300. It helps to keep things consistent.For a simple website semantic HTML or SMACSS can work, but for any semi-large scale websites with many variations of components it'll quickly descend into specificity hell. Using atomic classes keeps the specificity flat, and it avoids an entire category of errors that haunts many large projects just by making the styles sort of self-contained (you still need the stylesheet).
Of course there are other approaches to this problem such as "namespacing" your CSS using BEM and dynamically generating class names using CSS-in-JS, but using atomic classes is a very maintainable way to style HTML, if a little hard to read.
However, please avoid the snark. It diminishes the discussion. It took me a long time to come around to the idea, and the snark of (some of) its supporters was precisely part of the reason for that.
Edit: So after looking into it a bit more, and specifically the section in the documentation about extracting components, I understand where they're coming from a bit better. Extracting repeated compositions of utility classes into reusable components or named classes is exactly how I use other CSS frameworks such as bootstrap or foundation. I'm seeing the major difference between tailwind and other CSS frameworks as being the lack of pre-defined UI components. The minimalism is obviously a big advantage for performance, but otherwise I still see little difference between Tailwind and other CSS frameworks.