DEV Community

Cover image for Say no to Tailwind, embrace plain CSS
Hayk Baghdasaryan
Hayk Baghdasaryan

Posted on • Edited on

Say no to Tailwind, embrace plain CSS

Tools like Tailwind may help you develop your hobby project faster, but the thing is...

There shouldn't be any presentation logic in markup

You should use HTML to describe the content, hierarchy and structure, not how it looks. You should use semantic HTML tags like <section>, <aside>, <figure> instead of <div>. Then you style the content using the classes corresponding to the type of content, like "testimonials" instead of "bg-slate-100 rounded-xl p-8 dark:bg-slate-800".

That's why they removed a bunch of presentation tags from HTML, like <font>, <center> etc. Your website should be readable even without a single line of CSS/JS, only with the help of the right structured HTML. I encourage everyone to do some research on things like progressive enhancement and graceful degradation.

Benefits

There are tons of benefits in using HTML and CSS as they are intended to be used.

  • More accessible website,
  • better SEO,
  • performance improvements thanks to smaller HTML/CSS size and caching,
  • and you potentially avoid legal issues in future.

But... It's hard

Just because something is easier doesn't mean it's the right way to do it.

I get it, it's mentally draining to analyze the type of the content, name it correctly. But our job, as developers, is to do exactly that. Translate business requirements and domain knowledge to code, without ambiguity and without context loss.
It may be hard for some to learn CSS. The alternative? We learn a new framework, tool, library, utility every week. Learning and mastering CSS can't be much harder than that.

Conclusion

Tailwind may be great for hobby or POC projects. But for enterprise projects that tend to scale vanilla HTML/CSS is the way to go.

HTML and CSS are not perfect, but I'd rather we improve existing solutions, than come up with newer, shiny bad tools that try to solve the very problem they introduce.

Top comments (118)

Collapse
 
unsungnovelty profile image
Nikhil • Edited

Edit: Maybe I should add the fact that I moved my personal website from Bulma to Tailwind CSS which was 12726 lines of CSS to 805 lines of CSS. Which made my stylesheet go down from 247.1kb to 13kb. I already have had tried to use the minimum possible in Bulma. With Tailwind CSS load only the used CSS.


As a perfectionist, I am very picky when it comes to my choice of an abstraction layer. Tailwind CSS has been a great abstraction layer IMO. I wrote about it here as well - dev.to/unsungnovelty/explaining-wh....

But our job, as developers, is to do exactly that. Translate business requirements and domain knowledge to code, without ambiguity and without context loss.

This. Our job's to translate things to solutions. HOW we do it is irrelevant. A lot of companies (Especially VC funded), nor the end users care which tool we used. All they could care is whether they get what they want, the way they want it, by the time they want it. That is it.

But... It's hard

There is also something called Pit of success which was coined by Jeff Atwood. CSS is a perfect example of a tool which instead of directing you towards pit of success, directs you towards pit of despair. In short, a tool/technology/language by default should make it hard for you to fail and direct you towards success. And CSS is an example of pit of despair. And IMO, Tailwind CSS makes it much more manageable.

I love CSS as a technology. When I have time, I still write plain CSS to brush up my skills. I love CSS Grid a lot. But I would be lying if I say CSS is not a PITA. Also, Tailwind CSS still makes you think in CSS as I mentioned in the blog. Unlike component based CSS frameworks, for working with Tailwind CSS, you still need to know some CSS at least. And as you work with it, Tailwind CSS helps you learn plain CSS. Whereas component based CSS frameworks like bootstrap and bulma makes you forget what you know in CSS. It is far better than navbar classes IMO.

Personally I understand where you are coming from. At least I think I do. Cos I used to think similarly. But it's all about balance. And the right tool is extremely subjective based on your requirements and the time you have to name a few. :)

Collapse
 
haykerman profile image
Hayk Baghdasaryan

A lot of companies (Especially VC funded), nor the end users care which tool we used

This is the biggest part of the problem I've personally experienced. If they don't care, we're the only ones remaining who should still do, ideally. I don't suggest throwing out all existing frameworks right now and going Vanilla. I just advocate for using it more, improving it or at least trying to stick to best practices. Because clearly, the direction we're going right now is concerning.
I agree that it's all about balance, and using the right tool for the job.

Collapse
 
unsungnovelty profile image
Nikhil • Edited

I just advocate for using it more, improving it or at least trying to stick to best practices. Because clearly, the direction we're going right now is concerning.

That is a good POV. End goal being plain CSS. The utility classes does crowd HTML markup. Which is my only problem with Tailwind CSS so far. But developer experience Tailwind CSS provides is better for me though. And with components based frameworks like Bootstrap, I pay a lot in performance.

With Tailwind CSS, I bundle only what I use. So as a dev, I am more happy thanks to the developer experience (DX) and performance. So the truth is, at least for a some time, I don't see a reason to go back to plain CSS or component based frameworks.

Thread Thread
 
prototowb profile image
Tobias Rauer

Yes, tailwind can be nice for POC.
Although, tailwind let's you forget how to name things properly, and adds a big mess of obfuscated elements, and thus should never be used in production or just projects that scale.

Thread Thread
 
unsungnovelty profile image
Nikhil • Edited

I agree with the markup getting crowded with the utility classes. While it is not recommend IIRC, you can create components and redirect it to a class name and use Tailwind CSS that way. But this issue and naming convention which is not needed cos you are not using components anymore anyways against:

  • Better DX (If you know CSS). You definitely need to know CSS for this framework unlike Bulma.
  • High performance. Load only used CSS. Nothing more or less.
  • Rapid UI development.
  • Knowledge transfer from CSS to Tailwind CSS is very less. You are not learning a whole new set of class names and how to use it. Instead you are translating it to well selected utility classes which provides a well designed design API. To me utility classes are aliases of CSS properties, for most part.
  • Learn CSS while using Tailwind CSS. This is just bonkers. I can't say this for any CSS framework.
  • You can configure the framework extensively. and use CSS properties which are not natively supported by Tailwind CSS. You can also use any values with any units you want even though your utility class doesn't have that value.

This means, if I want to use a CSS property which is not yet supported in Tailwind CSS,

  • I can use it like [clip-path:circle(50%)]. Voila! I just used clip-path property which is not supported in tailwind CSS. Configuring a CSS framework is a long and bumpy road in other frameworks. Also, it kills the whole point of using a framework because of the way it is designed.

Also the same way, I can use any values with any units with a utility class like

  • For width, w-[80%] or w-[90rem]. This means I can use a value outside of the default width values natively without hacks.

I don't know about you. For me pros outweighs the cons. You get the best of both worlds. A framework's convenience and CSS's performance. If you are using a CSS framework today, Tailwind CSS is one of the best if not the best. Like I said earlier, there is always a price to pay with abstractions. It is up to you to see if the pros outweighs your cons for your project/product. If it does, you should use it and don't, if it doesn't. :)

Collapse
 
hollyw00d profile image
Matt Jennings

Nikhil,
You mentioned "Our job's to translate things to solutions. HOW we do it is irrelevant.".

I wouldn't quick necessarily agree with that because if dev A creates very confusing, hard-to-update code when dev B is working on it that's an issue.

However, if dev A creates code that is considered a "hack" by some developers but still gets the job done and isn't dangerous and dev B can update it that's OK.

Collapse
 
unsungnovelty profile image
Nikhil • Edited

Hey Matt,

I think you missed an important part which went along with the quoted statement. I said it is irrelevant to the employers and end users. I wasn't talking about developers.

The scenarios that you mentioned as well, both the scenarios are relevant to the developers. Not necessarily for the employers or end users as I mentioned earlier.

A website with the mentioned first scenario can succeed and the second scenario can fail if the translation of solutions and business doesn't go well. Also vice versa. I definitely agree with you on the fact that the developers should write clean and understandable code. And that we should avoid magic and hacks as much as possible.

But with regards to the topic at hand, I don't think Tailwind CSS is a hack. Also, it actually teaches plain CSS and provides performance while doing it. I cannot say the same for component based CSS frameworks which are always a performance hog and makes you forget plain CSS. They only provide performance value when they can be utilised to the max, which mostly will be in a large project. Otherwise there is a performance tax.

Apart from the utility classes crowding the markup, I don't see any problem here. Not to mention if you want, you can make those into components and use it that way. The official typography plugin also provides sane defaults to many html elements through prose utility class. So for me, the pros outweighs the cons by many a mile. But that is just my use case. I don't think one abstraction layer can make everyone happy. And that is fine. It's the same reason why we have many choices. :)

Thread Thread
 
hollyw00d profile image
Matt Jennings

Hi Nikhil,

I heard you say "Our job's to translate things to solutions. HOW we do it is irrelevant." Yet, I still believe that code solutions are still relevant to managers if trying to edit or add to the current code is extremely difficult and time confusing.

So yes, managers should definitely know in a general and easy-to-understand way if a previously created code is time confusing to add to or edit.

But, if code is structured in a way that's easy to edit and can be scaled up, then managers don't need to know as many details.

Collapse
 
jsn1nj4 profile image
Elliot Derhay

Unlike component based CSS frameworks, for working with Tailwind CSS, you still need to know some CSS at least. And as you work with it, Tailwind CSS helps you learn plain CSS.

This is something I've experienced too. I've even found myself going back to Tailwind's docs for looking up something about how CSS works (e.g. the different parts of flexbox).

Collapse
 
patiodaddiobbq profile image
John Dawson • Edited

A self-proclaimed perfectionist uses “Cos”; oh the irony! 😉

Collapse
 
unsungnovelty profile image
Nikhil

I completely missed this comment! :D

Collapse
 
andrewbogdanovtss profile image
AndrewBogdanovTSS

I can't agree more. I can say that your comment is better than the original article, lol )) I've been using Tailwind like frameworks on huge enterprise ecommerce projects with hundred thouthands of pages and I've seen only improvements when I moved whole thing to Tailwind. If I could name just one trully outstanding idea that appeared on the web in the last 20 years that would be Tailwind, it just changed everything for me.

Collapse
 
gorango profile image
Goran Spasojevic

I couldn't disagree more.

Being dogmatic in a fast-changing industry will only leave you in the mud shaking your fist at everyone else who's moving past you.

I recently migrated a large project from pure CSS to Tailwind - not only did we see huge performance improvements, we also improved development time and maintainability of the whole project. New devs no longer have to learn naming conventions or discover where CSS rules are being declared.

If you want to use plain CSS in your pet project, go for it. But don't shove these ideas down people's throats just because you have ideological oppositions to a new paradigm.

Collapse
 
haykerman profile image
Hayk Baghdasaryan • Edited

If you had performance, maintainability problems with plain CSS, it's not the CSS. It's the developers, engineering managers, and their ignorance towards best practices. And maybe, just maybe, unrealistic deadlines.

If new devs are having problems with CSS, there can be multiple reasons: the conventions were not properly communicated, the information was not publicly available, the onboarding process is not well thought out or last but not least, devs weren't qualified enough. And I don't blame them. It's just the current state of the world.

Now, granted, CSS is not perfect, but it's constantly improving with additions like variables, CSS modules. I am not shoving ideas down peoples throats, people are free to criticize my methods, as long as the criticism is objective. Also, I encourage critical thinking. The post above is just my take on things, and my opinion on how we should move forward. Everyone is free to disagree.

And, there are no dogmas, just some experience sprinkled with common sense. I'm pretty open minded. If you have a better solution, or you have your own take on the situation, I am happy to hear it. Because improving what we currently have is a collective effort.

Collapse
 
mellen profile image
Matt Ellen-Tsivintzeli • Edited

A class name isn't presentation logic, unless it is, in which case it's clunky and misleading. A class name should describe the content, on a meta level, e.g. "testimonial", not how you want the content to look, e.g. "bg-slate-100”. Describing how content should look is the job of CSS.

If you only use class names for presentation then you're missing the point.

Collapse
 
nexxeln profile image
Shoubhit Dash • Edited

Very bad take, if you don't like tailwind, thats understandable, but shoving that opinion down everyone's throat?

More accessible website

How does tailwind hurt accessibility?

better SEO

Huh? It's a CSS framework how will it hurt SEO performance? I don't think you know how Tailwind works. Tailwind creates a stylesheet at build time based on the classes you used. Therefore these is very less unused CSS, hence performance is very good. This will only boost SEO no?

performance improvements thanks to smaller HTML/CSS size and caching

What? Tailwind will almost always create a smaller CSS file in a large scale project.

Tailwind may be great for hobby or POC projects. But for enterprise projects that tend to scale vanilla
HTML/CSS is the way to go.

So you're saying Deno Deploy, PlanetScale, Ping.gg and hundreds more are hobby projects?

Never seen a worse and more incorrect take on Tailwind lmao.

Collapse
 
haykerman profile image
Hayk Baghdasaryan

Thanks for your feedback :)

Collapse
 
jafuentest profile image
Juan A. Fuentest Torcat

LOL no one's shoving anything down anybody's throat. At least not in this post.

Collapse
 
nexxeln profile image
Shoubhit Dash

The title is "Say no to Tailwind, embrace plain CSS" lol. Please read the post before commenting.

Collapse
 
dhravya profile image
Dhravya

yeah, i completely agree with this! Please research before writing this type of blog, because many beginners will be negatively influenced by this.

Collapse
 
andrewbogdanovtss profile image
AndrewBogdanovTSS

Can't agree more. We live in the era of blind people being guided by the blind people and unfortunately all those people have access to internet and time to write articles.

Collapse
 
t3dotgg profile image
Theo Browne

Good take

Collapse
 
rodrigomata profile image
Rodrigo Mata

I completely disagree in two main things:

  1. You are basically saying that using Tailwind means using semantically incorrect HTML, those are two separate things. You can be using plain HTML+CSS and still use pure divs, so I would emphasize on that and make a distinction, using Tailwind is not related to writing bad HTML code

  2. In your conclusion you say that it is used for projects that don't scale. It's totally the opposite. Tailwind is made exactly for projects that scale, specifically for those that have a color palette, themes, dark mode, responsive, accesibility. Handling all of those features in plain CSS is not only hard to maintain but more error-prone. Tailwind uses PostCSS which will also autoprefix your classes to support a variety of browsers and also will analyze the classes and remove from the production build those that aren't used. This is super helpful in production-enterprise-big projects, because saving a couple of KBs translates directly into money.

I can sometimes feel you that in order to make something production ready today, a lot of extra tools are needed, but that's the complexity of web development: supporting too many devices, screen resolutions and being performant and styled at the same time. In order for us to be able to use plain CSS and JS IMHO, we would need a new CSS and JS that is not backwards compatible, because that's the main problem, and in order to do that, you would need the reinvent the wheel. And there's nothing wrong with that, take Adobe Flash for example, it is now deprecated.

Collapse
 
haykerman profile image
Hayk Baghdasaryan • Edited

Completely agree on the 1st point. The semantic HTML pitch was practically an extra. I can see how someone reading the post may get an impression that using Tailwind is associated with writing bad HTML. My bad. I will try to edit it.

Somewhat agree on 2nd point. I never said that Tailwind is used on projects that don't scale. I suggest using it on smaller hobby or proof of concepts project. I agree that it may be easier to scale with Tailwind. I'm just implying that the cost of using it may be more than the advantages it provides. Of course it's just a tool, and it has it's advantages.

Basically this article turned out to be a little bit cheesier than anticipated. I think your take on this is healthier and more balanced. I appreciate the contribution and constructive criticism.

Collapse
 
andrewbogdanovtss profile image
AndrewBogdanovTSS

I really can't understand what "costs" you are trying to point to here? No one will crucify you if you write md:flex in your html

Collapse
 
fkranenburg profile image
Ferry Kranenburg

Classes are attributes of html elements. Tailwind classes are not html elements like font or center, so you can't compare them like you do. I don't think many front end developers are building pure html and alongside css elements. Who does that anyway? 'Components' in whatever framework you use, that include encapsulated styles, is the future an the way to go nowadays. Personally also not a fan of Tailwind but classes are still part of common html sematics.

Collapse
 
haykerman profile image
Hayk Baghdasaryan

Sorry if my post was not clear enough. I am not against using classes, I am against using presentation classes. I prefer "navbar", "features", "testimonials" over "bg:blue", "text-center". The markup should not contain information about how something looks.

Sure, Tailwind provides classes, not tags. But, be it a presentation class like "text-center" or a <center> tag, I think neither is acceptable or semantic.

Let's agree that "Who does that anyway?" is not a very good justification against doing it.

Using frameworks is not the only way to create websites. What happened to Vanilla JS? Almost everyone today creates websites using frameworks and component libraries. I don't think this is the way to go, though I understand why and how we got there. Honestly, this can be a topic for another article.

Collapse
 
joshistoast profile image
Josh Corbett

Yes, Javascript frameworks are not the only way to build websites, but they are the best way right now. Tailwind isn't being marketed to individuals building straight vanilla html/css/js sites, it's more for those where functionality takes center stage over styling than anything. Being ignorant to the way new web technologies and practices are evolving is only going to hurt your future projects and skill set down the line.

Thread Thread
 
haykerman profile image
Hayk Baghdasaryan • Edited

I've been and still am using those frameworks while working on multiple enterprise projects. I've experienced both pros and cons of those. I'm well aware of current trends, I've been closely observing the evolution of the web development, tools and methods for more than 5 years.

If you think this post is intended to just trash current tools and technologies, read again. While highlighting the weak points of a popular tool, this post is about wondering if there's a better way, and pushing innovation in the right direction while preserving established best practices. The intention is far from being ignorant. On the contrary, it's about caring enough to attempt improving what we already have today.

Without any doubt, how we're creating websites today is sub-optimal at best. Huge bundle sizes, millions of tools and dependencies, slow, not-accessible, unmaintainable websites. And the list goes on.

If you consider yourself a decent software engineer and take pride in being one, you should try to be professional enough to create quality products. But that's my take on the matter. Ultimately, it's just a matter of priorities. If you're just focused on making money, moving up the career chain, or surviving given the current state of the software engineering world, this discussion is pointless.

Either way, I wish you success, and I hope someday you will join me in an attempt to improve and perfect the technology, which will lead to the creation of amazing, performant and accessible products, the better web.

Thread Thread
 
fkranenburg profile image
Ferry Kranenburg

I don't think you really have a good view on how we noways should build good, nice, userfriendly and dev maintainable websites. Bundle sizes exceed but we also have more bandwith, faster devices an we need to add lots of features to compete with the competition. It is just how it works. But if you see unmaintainable websites using modern technologies than you are doing it completely wrong. In my 20 year web dev experience I watched us fighting various browser related issues (IE) and trying to get things work cross browser just by using lots of old hacks. I'm glad those days are mostly over because of our new much improved set of tools all self respecting developer should use today.

Collapse
 
fkranenburg profile image
Ferry Kranenburg

I agree on most parts, maybe I don't understand the difference between classes and presentation classes. I'm sure all classes are meant for presentation. But how Tailwind let's you add lots and lots of separate classes for displaying 1 html component is mostly very confusing an time consuming while fixing issues with styling. And it makes the pure html harder to read.

I try to stay away from 'Vannilla JS' written websites because nowadays using reactive frameworks, typescript, reusable components, scss makes my work a lot easier, less buggier, and takes much less time to build. Great article btw 👍

Collapse
 
alohci profile image
Nicholas Stimpson

Yes. Of HTML semantics. i.e. The meaning of the content. Presentation information should not appear in HTML classes.

Collapse
 
sebastianinman profile image
Sebastian Inman

According to who, exactly?

Thread Thread
 
tbroyer profile image
Thomas Broyer

Everybody for the last 20 years or so? …until people started reinventing inline-styles with "utility" css frameworks (the whole idea of "css frameworks" is…)

Collapse
 
huzaifams profile image
HuzaifaMS

I agree with you.

I used to use tailwind a lot but my mind changed after reading articles from Jason knight. I started learning css from tailwind but kept coming across roadblocks and having to use custom css a lot to get things working the way I wanted them.

After seeing how html and css are actually better and really all you need for most of front end development. I stopped using tailwindcss.

Mainly because it didn't make sense to me to put styling info inside of html itself. It was much more cleaner to seperate the styling from the content and structure.

I also learned that all those class names bloated the ht l for user agents who had no need for styling.

Honestly seeing how badly websites with frontend frameworks and css frameworks load on a slow 3g connection goes to show how bad the products were and how little consideration was given to performance as a default. You'd have to spend exponential amount of time to reduce page transfer sizes to kbs instead of mbs compared to properly using
Html
Css
Js
For what they each were meant to be used for.

Sorry for the ranting. Props for the article.

Collapse
 
thomasbnt profile image
Thomas Bnt

Oh, thank you for your article. 🙏🏼

I am currently working on a project that I have taken over. The team is using Bulma (same as Tailwind), and when I see that a class is called title only to give the font-size and two three parameters more, it makes me shiver.

Why do this knowing that there are already semantic tags...?

Collapse
 
rillus profile image
Riley

There's some great discussion here in the comments, and perhaps some of my contribution will have been covered, but I'd like to talk a little about my experience of both Tailwind and non-tailwind projects.

Tailwind serves a purpose, and it's good at what it does. It's not my first choice of framework for CSS, because I have extensive CSS experience and Tailwind is relatively new to the party, so if I'm working on a project with Tailwind I need to adapt my style slightly.

As an example: late last year I worked on a new project for a startup, and they'd chosen to use Tailwind. Their reason for doing so was simple and practical: their CTO was more of a backend developer than a frontender, and he hadn't done much CSS in his career. Tailwind removes issues of inheritance and cascading to a good degree, so he knew he could apply a class and style as he wanted without having to dive into CSS too much and learn about all it's intricacies.

I think Tailwind is great for prototyping quickly, and we got good traction early by using it, but as certain patterns emerged from the code, and as the codebase swelled, I found myself wanting (and perhaps even needing) a more structured approach. In order to reuse lengthy groups of classes, I converted some of these into CSS Components. This had the useful side-effect of reducing the size of the HTML, adding context to some elements and allowing us to update the style across multiple pages if needed. As a simple example, rather than having the heading definitions sprinkled throughout the project:

<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Enter fullscreen mode Exit fullscreen mode

Using Tailwind's @apply syntax, this becomes

<h2 class="Heading2">
...
.Heading2 {
  @apply font-semibold text-xl text-gray-800 leading-tight;
}
Enter fullscreen mode Exit fullscreen mode

While adding a class looks like more code, as soon as you have multiple identical h2 tags on different pages you soon start to benefit.

This problem could be mitigated with components in your favourite JS framework, but you may decide you don't need a component just for a header (until that header has more functionality you want to control), or you may decide that for simplicity the overhead of multiple identical headings using Tailwind is fine - that's cool. There's no wrong answers here.

Tailwind can be a great asset, but it can also be misused. I recently inherited some React code for a new project, and one page I need to work on is a contact form. The code starts like this:

<div className="relative bg-white">
      <div className="absolute inset-0">
        <div className="absolute inset-y-0 left-0 w-1/2" />
      </div>
      <div className="relative mx-auto max-w-7xl lg:grid lg:grid-cols-5">
        <div className="py-16 px-4 sm:px-6 lg:col-span-2 lg:px-8 lg:py-24 xl:pr-12">
          <div className="mx-auto max-w-lg">
            <h2 className="text-2xl font-extrabold tracking-tight text-brm-grey-900 sm:text-3xl">
              Get in touch
Enter fullscreen mode Exit fullscreen mode

I can read this and make sense of it, and I can run the project and see what's happening here, but it's not very pretty (to my eyes) and probably needs to be refactored into sub-components so I can reuse these styles on other forms I'll be building soon.

This code would also benefit from using semantic tags for context and SEO, but these are issues with this implementation, and not a problem with Tailwind itself.

The OP mentioned that Tailwind could be good for a hobby project. This is unnecessarily harsh, as Tailwind can (can does) work well on enterprise projects, but if you opt for it will depend on your team's strengths, your tech stack as well as your own personal preference.

So, don't "say no to Tailwind", say instead "what problem does Tailwind try to solve? And will it help my team deliver this project?"

Some comments may only be visible to logged-in visitors. Sign in to view all comments.