I changed my mind about Tailwind CSS

When I first got into contact with Tailwind CSS, I was slicing websites where I would use the Block, Element and Modifier (BEM) methodology together with Sass. This system suited my needs and provided ways to make a component reusable and structured. Reading through my code when everything was sliced felt clean and readable. When I read the docs from Tailwind CSS I thought it was more for people who didn't know CSS that well, it looked messy.

Block, Element and Modifier (BEM)

Don't worry, this article isn't going burn BEM to the ground. It still has its advantages and provides readable code. However, if you're using BEM, you've probably been stuck numerous times trying to come up with good names for your component classes. With time and experience it becomes easier as you know how to name things, but it can be annoying sometimes.

BEM example
<div class="article-preview">
  <div class="article-preview__visual">
     <img src="..." alt="...">
  <div class="article-preview__content">
    <time class="article-preview__publication-date" datetime="...">...</time>
    <a href="..." class="article-preview__title">

Tailwind CSS

So what's the deal with Tailwind CSS and why did I change my mind? It all changed when I started to code websites in Next.js, which uses React. Before, my components were just simple snippets of how a component would look like. I would list these components on a separate page and then copy paste them to where they were needed and change the data that was printed.

If I would've added TailwindCSS to my setup back then, I would have had to copy paste a lot of classes every time I would want to use it. That's why BEM was a better option back then. It greatly reduced the amount of classnames and it was easy to find all the snippets when I had to refactor them. This approach is sufficient when the project is small and when you're working alone. But when you're working on a bigger project with multiple people, things can get messy very quickly.

When using React, the situation changes drastically. You have a component that expects props, and the CSS class definitions of that component only need to be defined once. It doesn't matter that much if the generated HTML structure isn't as readable and compact as BEM anymore, because it's all placed into a single file.

Tailwind CSS example
export default function NavItem({ href, isActive, children }) {
  return (
        className={`block px-4 py-2 rounded-md ${isActive ? 'bg-amber-100 text-amber-700' : ''}`}

When I first started to actually use Tailwind, I was still pretty sceptical because of my background. A few days passed by and I soon realised it was a match made in heaven. My development flow improved because I didn't have to figure out how to name all those classes anymore, I could just use my CSS knowledge to code the layout.

The utility classes that tailwind provides are very helpful, it feels great for larger projects. The team can all use the same classes and everyone has the docs available from the get-go. Another huge advantage is that the generated CSS doesn't grow that much in size when your website grows in components. It might grow a bit over time, but it won't nearly be as much as when you use semantic class names.

There's nothing wrong to create some sensible default semantic classnames to use throughout your project. In practice, you'll probably use a mix of both.


When you're learning to code, you build up your own mental picture of how things work and what feels right. This picture adjusts over time as you learn and grow. At some points throughout your progress, you might feel as if the picture is perfect as is. Try to keep in mind that this is due to the fact that there's still information missing for you to expand that picture.

I thought semantic classnames and BEM were the way to go. I didn't even bother experimenting with Tailwind CSS. Nowadays, I'm very happy that it's part of my workflow. Maybe in a few months I could change my mind again and write a blog article about why X is better than Tailwind CSS. In development, nothing is set in stone.