Vanilla CSS or Tailwind CSS?

Tailwind has become very popular over the last few years, sometimes because it’s practical and sometimes because a lot of people find it easier than learning CSS properly.
I started using it only a year ago, on projects built with Astro, and it took me very little time to get used to it. Probably because I’d been designing with plain CSS for years: I already knew what I wanted to achieve and only had to learn how to write it as classes. That isn’t everyone’s situation, and I think it changes the answer to the question in the title quite a bit.
These days I use both, and here’s when I pick each one.
Where Tailwind wins
For layout work, Tailwind makes me much faster. I build the interface directly in the HTML, without jumping to another file or thinking about what to name each class, and everything comes from the same scale of spacing, colors and type, so the design stays consistent without effort.
It also fits Astro really well: since components are easy to reuse, the long class lists stay wrapped up in one place instead of being repeated across the project.
If I need to ship something quickly that’s organized and will keep growing, Tailwind is my first choice.
Where I prefer CSS: shadows and pseudo-elements
This is where Tailwind doesn’t quite win me over, and it’s one of the few things I don’t like about it.
Shadows, mostly. When I want a shadow with some depth I usually need several stacked together, and in Tailwind that ends up as an arbitrary class that’s hard to read:
<div class="shadow-[0_1px_2px_rgb(0_0_0/0.06),0_4px_8px_rgb(0_0_0/0.06),0_16px_32px_rgb(13_188_130/0.12)]">
In CSS the same thing reads at a glance, and if I use it in several places I change it in one:
.card {
box-shadow:
0 1px 2px rgb(0 0 0 / 0.06),
0 4px 8px rgb(0 0 0 / 0.06),
0 16px 32px rgb(13 188 130 / 0.12);
}
I know Tailwind 4 lets you define your own shadow in @theme and use it as shadow-whatever, and I haven’t dug into that yet. But even then I end up writing the shadow in CSS, just somewhere else.
Pseudo-elements (::before and ::after) are the same story. This is a real piece of the ::before on the project cards in my portfolio, written in Tailwind:
before:absolute before:size-36 before:aspect-square before:rounded-full
before:blur-3xl dark:before:blur-3xl dark:before:opacity-20 before:opacity-5
before:transition before:-z-1 before:left-7/12 before:bottom-50 xl:before:-bottom-0
before:[background-image:radial-gradient(circle,_rgba(71,255,194)_0,_rgba(0,255,191)_100%)]
dark:before:[background-image:radial-gradient(circle,_rgba(7,255,173)_0,_rgba(1,45,34)_100%)]
It works, but every property carries the before: prefix and dark mode duplicates half of it. In CSS it would be this:
.project::before {
content: "";
position: absolute;
z-index: -1;
left: 58.33%;
bottom: 12.5rem;
width: 9rem;
aspect-ratio: 1;
border-radius: 9999px;
filter: blur(64px);
opacity: 0.05;
background-image: radial-gradient(circle, rgb(71 255 194) 0, rgb(0 255 191) 100%);
transition: opacity 150ms;
}
.dark .project::before {
opacity: 0.2;
background-image: radial-gradient(circle, rgb(7 255 173) 0, rgb(1 45 34) 100%);
}
@media (min-width: 80rem) {
.project::before { bottom: 0; }
}
It’s longer, but it’s easier to understand and easier to maintain. When a style depends on lots of shadows or on a pseudo-element, doing it in CSS is more sustainable for me.
What each one costs
Plain CSS gives you full control and doesn’t depend on any tool, but it takes discipline: without good organization, between the cascade, specificity and class names, a project gets messy fast.
Tailwind removes most of those problems in exchange for very busy HTML and a build step. And if you don’t know CSS, it also takes away your ability to understand what’s going on when something doesn’t come out as expected.
My answer
I’ve never regretted picking one or the other for a project. I think that’s precisely because I used a lot of CSS before getting to Tailwind: today I can decide with confidence what suits each new project, and I often end up using both at once.
So my advice is to learn CSS properly first. With that foundation, Tailwind takes very little time to learn, and so does any other framework, however different: Bootstrap, Bulma or whatever comes next.

