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:
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.
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 😄


Latest comments (60)
There's this false idea spreading around that tailwindcss invented utility classes
Do we know if there is a way to just 'activate' tailwind classes without the integrated styling, e.g. Focus Ring and that? I its pretty annoying. I know I possibly could remove everything with @apply but that is a totally repetitive task for every new project. Any help is appreciated :)
Nevermind, found it with preflight:
tailwindcss.com/docs/preflight
The false dichotomy of the day is this:
vs.
For a more eloquent great case against using utility classes please read this: every-layout.dev/rudiments/global-...
Now my short opinion. Locally styling each and every component is bad CSS practice. You should have a lean vocabulary of well-defined bigger components and shapes. You see,
CSSis an exception-based language: you create a set of general rules, and then only write further ones, when you have to differ from those.Tailwind on the other hand, went full in with local styling.
When you have globally set general rules, you will have less changes required to change the appearance of the page. If anyone here remember CSS Zen garden, it was possible only because the classes on the items were semantic. CSS Zen garden would have never been possible using the tailwind approach.
Generating another style would instead mean to rewrite each and every component. Let's say: screen sizes grew and we can afford thicker margins? With tailwind approach now you have to go into each items and change those values. Because you have eliminated general rules from the equation, now everything is an exception.
This line:
<div class="px-0 pt-1 text-sm" />means that you want an average<div>except that it has no horizontal padding, it has 1 amount of top padding and it also has a special small set of font.If you are lucky enough someone in the team will have a brain to move it into "presentational" React component, that does nothing just the same thing
class="something"would do.I discovered Tailwind too late. I spent many years being a backend developer with a passion for a frontend. I took a great care to style my sites, optimize CSS and make them amazingly looking and responsive.
That was when I had plenty of time.
Now I manage teams and build SaaS platforms and the development time needs to be way more optimized. Tailwind is so good looking and so simple to use that it would be silly not to use it. It makes my teams and myself very productive. We haven't written any single CSS line in ages. On top of that I pay Tailwind UI which let's us quickly glue together the stuff we need. I don't understand how one can hate it.
As an example I did the whole UI for this in less than 2h (including responsive layouts):
salarioo.com
Since we are also talking about React I do understand those that hate React though. :-)
I don't think I'll ever stop thinking Tailwind is a footgun, generally speaking.
Other than polluting the markup, my main concern is that it's another cognitive layer on top of CSS. Meaning you have to learn Tailwind's "syntax" in order to use it. At that point, I'd be happy using CSS straight away.
Not to mention that Tailwind's syntax for some more-than-dead-simple cases (like a
calc, a custom property or simply targetting descendants) is clunky at best:I understand the nicety to use utility classes, but definitely not to make a mess out of your markup - that is now more like a
<div>-soup:This is taken straight from Tailwind's homepage, by the way. When you forfeit control of the meaning of your DOM, this is usually the result.
The main alleged advantages of Tailwind all seem very weak to me:
Yes, the last point means that you need to learn and understand some advanced mechanics of CSS that need time and effort to be fully internalized. Tailwind wins when the team has developers with less experience in CSS, because it's an easy-enough solution for all. But those less-experienced devs will also have the worst time when it comes to maintain their own code.
Your example is biased... In CSS you just need
padding... not 3 separate lines, like in your example.I wonder what is the best practice in Tailwind for grouping styles, in normal css you can do that with classes, and then create a special class to indicate a specific button style.
What I don't like is having to copy and paste the same classes over and over... I've used the @apply directive but not sure if its the best practice..
That's where the design mistake shows. In a well-architected CSS page, you set sensible defaults for main elements. You look at your HTML tags, you create sane defaults for them that already gets you 80% there. Then you create special HTML classes that will represent your main layout components: is it a main panel, is this a header, is this a label? And so on. You are 95% there.
Finally you look at the components which need adjustment and you define those rules. This is a top-down approach, requiring knowledge of CSS and HTML, also you should have a lot of certainty of what kind of application you want to build.
Tailwind's approach is to work in isolation, bottom-up: you get a design, you add HTML tags until it matches closely what they gave you and you move on. You don't discuss decisions, you don't factor in future changes, you go and get productive now. Perfect for companies where people want to work hard, but smart, scaling or future-proof are not requirements.
In my opinion, if you wish to write code for long-term, you have to understand good CSS architecture.
If you want a band-aid, you can also make presentational components, that now nothing about anything, they just accept
childrenand that's it.Which you can use as:
Its certainly the opposite of how I am normally used to write CSS, but maybe it plays well with the component based architecture...
It is not according to Adam Wathan himself.
So the @apply directive is the best way to group?
No, I mean Wathan discourages the use of
@apply.He provided it to ease the adoption of Tailwind, but he personally just chugs classes into the markup.
i love tailwind, not defined style, and easy to use css properties, all good
I understand the reasons, but I don't like it. I know that evolution is necessary, but I also see front-end as an amusement park without supervisors, there are good ideas emerging wildly, and just because it seems cool to me doesn't mean I'll go into production and have to deal with it in 5 years.
Lots of new technologies wanting to solve problems that aren't even problems yet, that will probably cause problems.
In the end, it is your responsibility to choose what works for you. It’s always a the matter of: “can I afford this abstraction/solution or should I choose battle tested tech?”
It’s the matter of what you think will be most stable and scalable for you software.
For instance, I regret choosing prisma as an ORM. It’s great for basic projects, but for larger projects that you need more control over prisma is awful outside of it’s schema and migration tool.
Is it bad on its own? No, just not perfect for what we’re building for multiple query related reasons.
Love its typings though.
Anyway, I’m all for new tech. Just make your judgment whether you should or shouldn’t use it. Don’t trust the hype.
But even with all the hype around tailwind, I found it useful. I don’t care about css much. Just want things to work, and tailwind provides me that out of the box without having to care about building my own set of standards. And 90% of the time it works 100% of the time.
interesting point of view 🤔
we usually think about the now and not about the distant future, but that is something we should keep in mind as well, so, fair judgement I would say
Separation of concerns is just another opinion from what software could be and it's a lazy way to measure if a language can or cannot provide what your business needs in CSS architecture.
Tailwind provides an easy interface to CSS by dropping most of its funcionalities and abstracting it's units and APIs. This is not wrong, not good for everything and hard to measure in an industry that sees CSS architecture as a liability. When we talk about CSS we can be sentimental about it, we can talk about perceived performance in how fast we code or how we feel when coding, and care less about how it makes sense in a business model and if it truly provides an API that does not rely on template and are tightly copled to an ecosystem providing functionality.
Today tailwind future is bright and we can afford not to think about CSS at all, and abstracting even further regarding of its limitations, and it's ok, even if it does not makes sense > every time < business wise as the community makes it.
As you said the wheels always turns, it's good to see some fresheness, but I wish the discussion regarding CSS technology were deeper than the surrounding Tailwind are. Knowing it's limitations is also a power that makes you use it wisely.
The same idea is repeated with ORMs which in my opinion comes from a very greedy point of view: we don't have time to understand something in depth, we want it immediately.
This is not a bad thing, on its own, when you work on prototypes and do market-research and you try to land what exact features bring value to people.
But then, eventually, successful companies need to scale; they start serving more people, the amount of data grows very large under them and so on.
You can't afford not understanding how SQL works, how the specific database you use work. You would do tons of ineffective queries with an ORM that can be into 1 query 1 round-trip with a mid-level SQL knowledge.
Same is true with CSS: you can design a set of rules that are easy to change, but if you don't understand it, and with the magic framework for hiding it for you, you won't be able to achieve certain effects, you will struggle a lot with a design change, your code will be brittle and ineffective, because there were much simpler ways that even a mid-level CSS developer would have created for you.
Why I am angry with bootstrap and tailwind and the rest, that they are no longer sold as a great tool for rapid prototype; we are told that it is "evolution", it is the logic next step.
It is not! Neither are ORMs. You can't skip learning your craft. You will need it eventually.
I hope this is just an unfortunate way you expressed yourself, because that would be a terrible approach. Tailwind does not save you to learn and think of CSS.
Yes It does. Don't get me wrong, theorically I'm with you. In practice people could care less what Tailwind outputs as CSS as long as it works layout-wise - and the industry doesn't seem to care as well, CSS architecture is hard to grasp, to mantain and to enforce certain patterns.
So when I say
I'm saying that you can write the most verbose, repetitive, media-query full class based CSS and don't ever open the devTools again nor check the output code as long as layout works, relying only in template based reuse, JIT and compression in matters of performance, as if it were enough (it isn't).
And that's the point. Because almost nothing works on the first try, you'll eventually have to debug, and understand what's going on. And devtools presents you CSS, not Tailwind - which is not, and will arguably never be - a first class citizen.
I won't even mention that Tailwind's own documentation is full of references to the corresponding CSS properties and/or mechanics, so you have to know CSS to understand what Tailwind means.
What you're imaging - an abstraction layer that renders knowing what's under the hood completely optional - is a pipe dream that will eventually collide with reality (and in the case of Tailwind it fortunately happens very soon).
It's not something we haven't seen in the frontend community, mind you. Back in the day, there were jQuery developers who hardly knew anything about the DOM or even JavaScript. More recently, we have React developers who get lost outside of it. Accumulating knowledge debt isn't a route with a good outlook, although it seems sufficient in the short term.
I really hope you are right, because when there is an error with jQuery, it'll certainly break the application. CSS errors, verbosity or misconceptions are way more cheaper and overlooked, even if the layout breaks at some point. I had this problem working with CSS, SCSS and even Styled codebases, but with Tailwind is worse, not only because the thicker abstraction layer, but the community around it.