DEV Community

Cover image for How to keep Tailwind DRY

How to keep Tailwind DRY

Charlie Joel on August 06, 2021

There's many complaints I see online about Tailwind: it's WET, not DRY, it's the same as inline styles, you can't make global changes, and it's har...
Collapse
 
iamntz profile image
Info Comment hidden by post author - thread only accessible via permalink
Ionut Staicu

When is the right time to use Tailwind CSS?

Never. The right answer to this is never.

Collapse
 
charliejoel profile image
Charlie Joel • Edited

Care to elaborate on why you think so?

Collapse
 
iamntz profile image
Ionut Staicu

Everyone tries to do complex mental gymnastics to find the usefulness of Tailwind, when, in fact, it brings (almost) nothing useful to the table.

Adding 25 classes to an element? Cool, how is that better than adding inline styling? Just because you can do hover & media queries? Oh, that changes everything!

But wait, you don't have to add tons of class names, you say, just extract it into a component! Good idea, but why you'd use tailwind class names instead of... you know, plain css?

- @apply text-black text-24 bold;
+ color:black; font-size:Xrem; font-weight:bold;
Enter fullscreen mode Exit fullscreen mode

Then you have class names like text-black or text-green and the client ask you after a while: you know what? Let's make that black a dark gray and that green... blue. Sure, let's do a search & replace across all codebase, but now instead of having a diff with 5 files with 1-2 lines changed, we have 43 files with 10 changed lines each.


Just like bootstrap, Tailwind is another great example of things that were adopted wrongfully by the developers. Instead of using them as frameworks to create proof of concepts, they blown into abominations like „Tailwind themes” or „Bootstrap layouts”.

CSS evolved so much lately (with great browser support) that we, developers, shoot ourselves in our foot with tools like that and then cheer like mad mans. Tailwind is basically a solution to a problem that does not exists.

Thread Thread
 
charliejoel profile image
Charlie Joel

I hear you, this is a really common complain I see and it's understandable. I think the problem that Tailwind is primarily solving is excessive CSS bloat, which is 100% a problem with regular CSS. Using something like BEM you're guaranteed to repeat yourself which adds more bloat. So that's the problem, which I would say exists and is something people who are really concerned with performance could use a solution for. I think that's the main reason anyone would use Tailwind.

Most of this article is about how to avoid composing classes because I agree, you lose the benefit of Tailwind by using @apply too much. If you do that you may as well just use BEM with plain CSS.

Now how to change text-green to text-blue. To solve this you can use the same thinking as when writing SCSS variables: give the colours generic names. Instead of text-green you could call it text-primary or text-alpha, and if that colour needs to change just change the primary colour in your config.

What if it's not just every instance of text-primary you want to change? At that point, if you wanted to change individual elements surely there is no difference between that and changing the colour in the CSS?


// These are the same
// my-component.scss
.my-class {
  color:  $secondary; // changed from $primary
}

// MyComponent.jsx
<div class="text-secondary"></div> // changed from text-primary

Enter fullscreen mode Exit fullscreen mode

I can understand that it's completely different to regular CSS. I won't pretend there aren't limitations that need addressing. You might not want to change your methodology to something totally different in many ways. As I say it's not for everyone; it might not be right for your website, but for enterprise-level applications that need the speed boost and can benefit from the component-centric way of working I think it's got huge potential.

Thread Thread
 
iamntz profile image
Ionut Staicu

Tailwind is primarily solving is excessive CSS bloat, which is 100% a problem with regular CSS

By moving that bloat to HTML.

Actually BEM solves many problems in a very predictible way. At any point, if you see a class COMPLETELY out of context, something that reads like .hero__content__media--is-video you're pretty sure where is that piece used. Now compare with that mambo-jumbo Tailwind introduce.

You say it's better for enterprise? Sure, what it's easier to document? hero__content__media--is-video or p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4 ? button-primary or px-4 py-1 text-sm text-purple-600 font-semibold rounded-full border border-purple-200 hover:text-white hover:bg-purple-600 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-offset-2?

I'd say Tailwind has the same utility as Pug, HAML and other monstruosities that poped out in the last 20 years. Let's pause for a moment and think how hyped this language was if it wasn't pushed by Wathan & co.

Thread Thread
 
terabytetiger profile image
Tyler V. (he/him)

It's fine to just say you don't like Tailwind 😊 Everyone likes different things.

At any point, if you see a class COMPLETELY out of context, something that reads like .hero_content_media--is-video you're pretty sure where is that piece used.

Personally, the thing I don't like about this is that as a new developer on a project, I don't know what .hero__content__media--is-video is going to add when I add the class. And by extension I don't necessarily know everywhere that class is used if I wanted to modify the class in some way.

Every approaches has pros and cons, especially with something like CSS that is so flexible. If BEM works best for you, rock on 🤘🏻 But that doesn't mean you need to say that another approach should never be used.

Thread Thread
 
charliejoel profile image
Charlie Joel

I'm not sure who Wathan & co is, but it sounds like you're not going to like the framework anytime soon.

For the sake of answering your question, I think that a component called which has all the structure, styles and CSS associated with that component under the same folder is much easier to document than a SCSS file stored completely separately from the HTML itself, because you only need to look in one place to find everything related to that component and you could easily reuse that component in another project just by copying one folder. You could still use BEM for that, but you'd have a larger bundle size than if you used utilities only.

What I suggested in the article is that you'd never see a class completely out of context, because it would be attached to a JavaScript component or named in a variable. That's the context for how the class is used.

I wouldn't say the bloat is moved to the HTML in Tailwind unless you're just using plain HTML, which as I said you probably shouldn't be doing. Even then, GZIP can compress Tailwind classes much smaller than BEM classes due to how similar many of the classes are, often only having one character different between groups such as mb-1, mb-2 etc. So even if you were to copy and paste HTML, which isn't recommended, you'd still end up with a smaller bundle compared to BEM.

Thread Thread
 
iamntz profile image
Ionut Staicu

Even then, GZIP can compress Tailwind classes much smaller than BEM classes due to how similar many of the classes are

Actually... not really. The simplistic way archiving works (be it gzip or anything else) is that it:

  1. splits the whole thing (what needs to be compressed) into blocks for 4-8-16kb
  2. creates a dictionary for repeating chars in each of this block

That's why text documents compress so well.

The size argument is not valid, the gain is marginally in most cases.

Collapse
 
mohdahmad1 profile image
Mohd Ahmad • Edited

use windicss, it does not require autoprefixer or postcss. just works with build tools like webpack, rollup, vite or many more interaction available. It is 100% compitable with tailwindcss i.e provides same classes with some extra variable classes like m-{size}px, it works, windi css JIT handles it all

Collapse
 
charliejoel profile image
Charlie Joel

Haven't heard of this one before - I'll check it out!

Collapse
 
blindfish3 profile image
Ben Calder

A lot of the advice you give here is good; but there's also a lot here that doesn't feel specific to Tailwind. Component-based frameworks scope CSS to components; so it's definitely good practice to break an application down into "small re-usable pieces" and this already solves some problems in terms of HTML code and design consistency etc. without the need for BEM.

But the component-based approach comes with its own set of problems; specifically related to theming and unified design. I think developers got hung up on the idea that a component should be some isolated element that can be taken out of project A and re-used in project B and work and look exactly the same. So they wrote component styles to handle all aspects of the component's styling in isolation; but that makes maintenance and future global changes very difficult. It also tends to introduce a lot of duplication. But, unless you're specifically building a UI library, isolated styling is rarely a concern; and so introducing global styles is not an issue...

And from my perspective that's all Tailwind is: a global set of utility styles with some handy configuration built in. The same result can be achieved with any well maintained global stylesheet. Issues around theming and consistency in component styles can also be solved with pre-processors (e.g. SCSS variables; mixins etc.) or to some extent CSS variables. I'm not saying don't use Tailwind; but I've seen too many articles that claim it's a magic bullet to styling; when really it's just a well-packaged tool that addresses an already solved problem.

Collapse
 
owenmelbz profile image
Owen Melbourne

Your perspective seems to be focused on a subset of type of businesses/organisations. e.g We're an agency - no 2 websites are designed the same. A website will get built, launched, general maintenance, until 5-10 years down the line the client wants a brand new website anyway. So having any requirement to "theming" or global changes - has never happened for us and a client in 10 years. So don't worry until it happens!

Collapse
 
charliejoel profile image
Charlie Joel

Can't disagree with you there, I agree that this approach has its own problems. Hopefully these can be solved over time.

You could apply this article to any component based style; I talked about Tailwind specifically, first because I see it get a lot of hate that it doesn't really deserve, and second because that's what I've got experience with. I've used it on several projects which had really fast turnarounds and I wouldn't have been able to get those over the line if I was writing custom classes, even if those classes were isolated. That's the reason I use Tailwind over other solutions, it's really fast and easy to use and it follows a design system instead of random amounts of space. But I won't deny you could get a more custom look with a different method.

It's also not the best to use if you think your theming will change, though there's plenty of ways to mitigate that. I prefer it for headless applications over traditional websites. All about choosing the right tool for the job!

Collapse
 
owenmelbz profile image
Owen Melbourne • Edited

Good article, with some nice examples!

It would be beneficial to people still learning to remove any loaded content such as "You might be able to get it to work with PHP templates, but I'd say this method is best for JavaScript" - You can absolutely and 100% do this with PHP with great ease, and other languages like Ruby, .Net etc etc etc - Remember they've been around longer and more mature so can handle this stuff in their sleep, we do it every single day, and it is in fact easier as those languages have less boilerplate than React/Vue/etc.

Collapse
 
charliejoel profile image
Charlie Joel • Edited

I hear you, I don't think I explained my reasoning very well there!

You're right, you can definitely get this working with PHP and any other language using templates. The reason I prefer to use JS is

  1. Control over styles isn't limited to the backend - you could make a button add/remove a class, for example, which takes longer to do with inline JS.
  2. You can keep everything (JS, HTML, CSS) in one area. I know you could just make a tag in PHP, but that JS would be in the global scope without taking extra steps and (to me) it feels a little clunky.

With that said, I can already see holes in my arguments - at this point it's more to do with my personal preference/experience. I do encourage working like this in non-JS environments, but I'm not an expert in that area!

Collapse
 
alexanderop profile image
Alexander Opalic

Good Post I learned Something new

Some comments have been hidden by the post's author - find out more