DEV Community

Cover image for Hate on Tailwind... I have seen that before!
Nícolas Gabriel
Nícolas Gabriel

Posted on

Hate on Tailwind... I have seen that before!

In 2013, a company called Facebook introduced a framework called "React," which allowed developers to blend their JavaScript logic with their HTML code without having to modify the document directly.

This, my friends, was JSX, or JavaScript Extended, where you could write HTML within your JavaScript! I was just 9 years old, and I didn't know anything about programming, but the rest of the community had strong opinions about it when it was released.

"The audience was skeptical. Most people thought React was a significant step backward." - at JS ConfUS 29/05/2013

React was innovative because it challenged many established best practices of its time.

Separating JavaScript from HTML? Discarded.
Direct DOM manipulation? Discarded.
Two-way data flow? Discarded.

However, its boldness was a double-edged sword. Just as there were people excited about this innovation, others thought it didn't make sense. "Mixing JS with HTML? It will create more complexity and reduced maintainability.".

Some had been mixing JS and HTML before, such as in the MVC design pattern, which had a Model to manage logic, a View to render the UI, and a Controller to mediate between them.

Creating code that resembles React:

MVC

In computer science, there is a concept called "Separation of Concerns," which involves separating sections into their own contexts. In other words, you write your HTML in an HTML file, your CSS in a CSS file, and so on. This was a significant reason many opposed React.

Fast forward to today, React is the dominant framework. It's quite remarkable. But how does all of this relate to Tailwind? What about today?

Similar to React's history, Tailwind challenges many of the best practices we used to preach. Some people appreciate the advantages it offers, while others believe that the benefits don't outweigh the drawbacks.

Some dislike it due to its verbosity, but that doesn't make much sense (example in the image):

Verbosity - the quality of being wordy, speaking excessively, or using too many words to express oneself.

Comparison Tailwind and CSS

The real problem is with the "separation of concerns" mentioned earlier, and in this respect, Tailwind falls short. It's okay for CSS to have 1,000 lines if it has its own file, but a class with 1,000 words pollutes our HTML/JSX.

There are third-party libraries like Tailwind Fold, but there's no native solution that resolves this 100% and is considered a good practice (im looking to you @apply).

With this article, I didn't intend to persuade you or provide a solution, but rather to tell a story and help you understand that this kind of debate has occurred in the past.

As George Santayana said, "Those who cannot remember the past are condemned to repeat it."

Who knows, maybe in 10 years, Tailwind will also become one of the most famous ways to write CSS? Only time and its evolution will tell.

Anyway, thank you for reading!
Have a good day 😄

Oldest comments (60)

Collapse
 
zkriguer profile image
zKriguer

Thats a good approach, thanks for sharing your experience with both ways to do CSS.

Collapse
 
sultan99 profile image
Sultan

Actually, Tailwind is the next evolution in styling. Before CSS, we used to style elements like this:

<p>
  <font color="red" face="Verdana, Geneva, sans-serif" size="+1">
    <b>Your formatted text goes here</b>
  </font>
</p>

Enter fullscreen mode Exit fullscreen mode

However, this approach was deprecated with the introduction of CSS. With Tailwind, we are revisiting the concept, but instead of using attributes, we now put all styles in a className with shortened classes. This madness pushed me to come up with a new idea: importing styled React components from a CSS file, where all style manipulation can be done through component properties:

import { Title } from './styles.scss'
// crazy part, importing 👆 component from styles

<Title color="tomato" size="small">
  Hello world!
</Title>

Enter fullscreen mode Exit fullscreen mode

Where style.scss file looks like this:

/**
  @tag: h1
  @component: Title
  size: small | medium | large
  color: #38383d --color
*/
.title {
  --color: #38383d;
  color: var(--color);
  font-size: 18px;

  &.small {
    font-size: 14px;
    margin: 2px 0;
  }
  &.medium {
    font-size: 18px;
    margin: 4px 0;
  }
  &.large {
    font-size: 20px;
    margin: 6px 0;
  }
}

Enter fullscreen mode Exit fullscreen mode

For more information, please check out the demo and repository:

Online demo
GitHub repo

Collapse
 
nickgabe profile image
Nícolas Gabriel

That's a super interesting idea! Loved the concept!

Collapse
 
joshuaamaju profile image
Joshua Amaju

That tell's me all I need to know about your position on tech choices 😂

Collapse
 
syeo66 profile image
Red Ochsenbein (he/him)

You might want to take a look at PandaCSS for a similar but framework agnostic approach.

Collapse
 
sultan99 profile image
Sultan

There's nothing particularly unique about Panda CSS in terms of its idea or approach. Many CSS-in-JS libraries offer similar ways of styling.

Thread Thread
 
syeo66 profile image
Red Ochsenbein (he/him)

Tailwind isn't a new idea either.

Thread Thread
 
sultan99 profile image
Sultan

Yeah, but Tailwind made this approach popular, just as styled-components popularized CSS-in-JS. Other CSS-in-JS libraries introduced additional features, such as build-time extraction and shortened CSS classes, but in general, it is the styled component approach.

What I know is that there are several ways to style components:

  • CSS module
  • CSS in JS (styled-component way)
  • Tailwind
  • Inline styles
  • Stylin with mapping style annotations

P.S.: If I had to choose between Tailwind and PandaCSS, I would pick PandaCSS.

Collapse
 
learncodeprofessor profile image
LearnCodeProfessor

Great post!

Collapse
 
xwero profile image
david duymelinck

I think you don't need to overstate popularity. It is not because it is popular it is the best solution for your application/website. The only reason popularity wins is because it has solutions you can copy paste.
People build things because it serves their needs. But you have to figure out what your needs are before saying without this and that every project will fail.

I do more server side code, but i know how important it is to push only the code that is needed to the browser. Doesn't matter if it is javascript, css or html.
On the server we have less of a problem with big codebases because the user only finds out when the response is slow.
For frontend code the penalty is upfront, because the user has to wait until the code that makes the page work is loaded.

Tailwind for me is a good idea, utility classes, that is taken to the extreme. And that is always a bad way to go. Figure out what is the balanced solution for your usecase and everyone is going to be happier in the long run.

Collapse
 
efpage profile image
Eckehard

Maybe we should look at the topic a little more generally...

HTML is not the first language to build User interfaces. If you write an application for windows, linux or apple, things are very similar. If you need an input field, you will define it in a similar manner you do in HTML. But in traditional applications, you do not have so much control over the appearance, in fact, most visual components are styled by the OS, not the application. This may limit the developer, but gives a better user experience. Companies like Apple have their Human Interface Guidelines to ensure a uniform user experice - something we would whish we had for web developers today.

HTML / CSS was initially not designed as a UI toolkit, it was designed to apply better styling to static documents. The more the web is used to build applications, the more the conceptual issuses of CSS/HTML will be visible. The web is evolving from a presentation platform to an application platform. Any modern CSS toolkit should support this evolution, so future will show, if tailywind does the job.

Collapse
 
fabiovaz profile image
Fabio Vaz

I love work with tailwind, so much fast.

I would like to just add one fix to your css “px-0 pt-1 text-sm”
In css its was something like
padding: .25rem 0 0;
font-size: .75rem

This just 2 lines will be the something

Collapse
 
nickgabe profile image
Nícolas Gabriel

Tailwind sets the properties one by one, not the shorthand afaik
tailwindcss.com/docs/padding

And the text-sm also adds the line-height
tailwindcss.com/docs/font-size

Collapse
 
fabiovaz profile image
Fabio Vaz

Yes I agree. But to make a comparison whether the tailwind is verbose or not, we also need to use a correct CSS structure, or it would be like me demanding that the tailwind be set to "pl-0 pr-0 pt-1 pb-0". I believe that the text is not how tailwind renders it, but rather a comparison between tailwind and css in terms of verbosity.

In relation to the line height, in the tailwind it also sets the arrow to make it easier to change the "leading". But the default line-height is 1.2, without being in rem. It also becomes proportional to the font-size.

Thread Thread
 
nickgabe profile image
Nícolas Gabriel

Oh ok ok, I got your point now. Makes sense, I made a comparison against its own "production" code, but you're correct, we would not write it that way as if we were writing CSS directly.
Thanks for clarifying

Collapse
 
artxe2 profile image
Yeom suyun

I don't like Tailwind very much, but its growth is overwhelming.

Collapse
 
maxart2501 profile image
Massimo Artizzu

Is it?

Since the last year:

  • "not interested" remained stable (25% to 24.9%);
  • "interested" fell quite some (25% to 22.1%);
  • "would use again" grew some (36.4% to 38.2%) but
  • "would not use again" grew even more (9.8% to 12.3%).

To be fair, Tailwind is probably more used than ever, but don't take that survey for a statistically strong example.

Collapse
 
siy profile image
Sergiy Yevtushenko

There are reasons for hate. Take a look at this article. I'd suggest read other articles from this author too. It's not a plain dislike or taste based hate. It's well grounded position. But, well, language might be somewhat offensive to some framework lovers.

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix • Edited

The biggest / most fair critique against tailwind I heard against is

  • it makes things hard to read, by/if using multiple lines of tailwind classes
  • using many divs in sequence - that makes it hard to distinguish between them
  • you have to memorize that all the shortcuts mean, ex. p-1 text-sm

Here is an Article with said critique in more detail
nuejs.org/blog/tailwind-vs-semanti...

I feel like the critique comes most often from designers, who translate figma design into html/css and have less knowledge on how to write idiomatic react code.

First 2 problems are solved if

My biggest grip with react + tailwind is, that I wish I could shorten className to just c or class, because it is such a long word to type out and it takes to much screen / line space.

Collapse
 
moopet profile image
Ben Sinclair

That's a good linked article.

Collapse
 
maxart2501 profile image
Massimo Artizzu

I feel like the critique comes most often from designers

The set of designers that do HTML/CSS development is definitely non-empty, but it's not the norm IME. Figma has also a decent Tailwind plugin for the matter, so they wouldn't even sweat to translate their design into Tailwind mashups.

First 2 problems are solved if

  • extracting said divs into separate components
  • using libraries like
    • tailwind merge - github.com/dcastil/tailwind-merge
    • and cva - github.com/joe-bell/cva
    • to merge and group class names

I fail to see how tailwind-merge could improve readability, while the others basically throw one of the main advantages of Tailwind out of the window: eliminating the necessity of naming things.

My biggest grip with react + tailwind is, that I wish I could shorten className to just c or class, because it is such a long word to type out and it takes to much screen / line space.

I personally never write className in full, because the IDE suggests it right away when I type just c, but I'm amazed to see that you consider className "too long" while the value could be something like bg-white border-slate-100 transition-all duration-500 demo-dark:bg-slate-800 transition-all duration-500 demo-dark:border-slate-500 border-b rounded-t-xl p-4 pb-6 sm:p-10 sm:pb-8 lg:p-6 xl:p-10 xl:pb-8 space-y-6 sm:space-y-8 lg:space-y-6 xl:space-y-8.

Collapse
 
adaptive-shield-matrix profile image
Adaptive Shield Matrix • Edited

while the value could be something like "long lines of tailwind"

I group similar tailwind classes together

Example:

export function CardWrapper({ children, className }: { children: React.ReactNode; className?: string }) {
  return (
    <div
      className={cn(
        "rounded-lg  shadow-lg", // card border + shadows
        "p-4 lg:p-8", // padding
        "bg-white dark:bg-gray-900", // bg
        className,
      )}
    >
      {children}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

somewhere in ui / utils

function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
Enter fullscreen mode Exit fullscreen mode

In the long lines of tailwind classes you provide

  • why do you not group tailwind classes (like in the example above)?
  • why do you not separate it into a separate component (like in the example above)?

Separating into function components like in the example

  • Is the example above hard to read?
  • Will it be if you add some more lines of tailwind classes in the same way?
  • I can give an example with even more tailwind classes following same pattern and I find it is very readable and maintainable for myself.
  • The only downside I see is you have to write many separate function components and naming them (vs similar how you have to define/name things for in css).
Thread Thread
 
maxart2501 profile image
Massimo Artizzu
  • why do you not group tailwind classes (like in the example above)?

Because it's not straight from the source - it's the output, taken directly from Tailwind's homepage. If I have to debug a problem, that's something the dev tools presents me.

  • why do you not separate it into a separate component (like in the example above)?

Common answer: because I don't want to name things.

  • Is the example above hard to read?

Definitely harder that reading plain CSS, yes.

Collapse
 
aquaductape profile image
Caleb Taylor

My biggest grip with react + tailwind is, that I wish I could shorten className to just c or class

There's solidjs, lit or preact that uses just class attribute

Collapse
 
jhedtmann profile image
Jörg Hedtmann

"The audience was skeptical. Most people thought React was a significant step backward." - at JS ConfUS 29/05/2013

Thats why it was called "React" as in "reactionary"...