Design and development

Tailwind CSS: why I use it in almost every project, and how I set it up with v4

Why I use Tailwind CSS: design tokens in @theme, CSS that does not grow, components instead of repeated classes, light and dark themes on variables. With the real limits and when I do not recommend it.

Fabio Folgori5 min read

A fan of colour swatches arranged in sequence
Photo by Mika Baumeister on Unsplash

I use Tailwind CSS in almost every new project, this site included. Not because it is fashionable: after years of stylesheets that grew with every page and class names nobody dared touch, it is the tool that has given me the best balance between development speed, design consistency and CSS weight. Here I explain why, how I set it up with version 4 and, just as frankly, where I do not recommend it.

The problem it solves

Traditional CSS based on semantic names (.product-card, .hero-title) has a structural flaw: it is global and grows by addition. Every new page adds rules and exceptions, specificity piles up, and after a few years nobody knows what can be removed without breaking a distant page. The result is a file that only grows.

Tailwind moves styling onto the element, with atomic classes that use a finite vocabulary: the project's spacing scale, palette and type sizes. Each class affects only the element it is written on.

Why I use it

Design tokens are the vocabulary

With v4, tokens are defined in CSS, inside @theme: colours, families, spacing scales, radii, shadows. They become native CSS variables and, at the same time, the only classes available. If the project starts from a Figma file with its own variables, they become the theme one by one (I explain this in From Figma to WordPress). An "almost identical" blue cannot creep in by mistake.

CSS stops growing

The published CSS contains only the classes used in the templates. The vocabulary is finite, so a new page reuses existing classes instead of adding rules. Stylesheet weight stays almost constant: a direct benefit for loading and rendering, which I cover in Core Web Vitals explained by a developer.

Local, safe changes

Changing a component's look has no side effects elsewhere. For whoever inherits the project, or for an agency handing me part of the work, it is the difference between making changes calmly and being afraid to touch anything.

Responsive, states and container queries in one place

Variants for width, hover, focus-visible, disabled, reduced-motion preference and container queries are written next to the base class. Focus and accessibility states become part of the component, not a forgotten add-on.

How I set it up

Components, not repeated classes

The most common criticism ("the HTML fills up with classes") is fair if you write everything inline. In a Nuxt or Vue project every recurring element is a component: a button's class combination lives in a single file. I use @apply sparingly, only for small shared base classes.

Light and dark themes on variables

On this site the light theme does not duplicate classes: it remaps the theme's colour variables. White becomes ink, the grey shades invert, and every component using the tokens changes on its own. The few "islands" that must stay dark (the work slider, the code window, the game) declare the dark theme on their own container. One place to check contrast, instead of hundreds of dark: variants.

Long-form content

Article text comes from Markdown and has no classes: it is handled with a dedicated set of typographic rules applied to the container.

The limits, plainly

  • You need to know CSS. Tailwind does not replace it, it makes it faster to write. Anyone who does not understand flexbox, grid and the cascade will not get there through classes.
  • Without component discipline the markup really does become unreadable.
  • It does not graft well onto ready-made themes and page builders, where styling is decided elsewhere.
  • Very special effects (complex animations, shaders, masks) are still written in dedicated CSS, and rightly so.

When I do not recommend it

On a WordPress site built with a ready-made theme that works, or for a small change to an existing site in traditional CSS, introducing Tailwind makes no sense: better to respect what is there. The tool is chosen for the project, not the other way round.

What changes for whoever commissions the site

You do not need to know what Tailwind is to see its effects:

  1. Lighter pages, because the published CSS contains only what is used: a measurable benefit, especially on phones.
  2. Visual consistency across the site, because colours, spacing and type come from a single token system.
  3. Faster, lower-risk changes: changing a detail does not break distant pages, and the cost of later work stays predictable.
  4. Code others can read: Tailwind is a widespread standard, so an agency or developer coming later finds familiar conventions, not a system I invented.
  5. Light and dark themes, focus states, responsive variants designed with the component, not bolted on at the end.

For an agency there is an extra benefit: the tokens of its own design system become the site's theme, and much less is lost between the design file and the code.

My take

Tailwind is part of a set of consistent choices: Nuxt and Vue for structure, small reusable components, design tokens as the single source of colours and sizes, pre-generated sites published with GitHub and Netlify. Each one reduces the number of things that can go wrong. It is the same principle that has led me to use fewer and fewer ready-made themes and page builders: fewer layers between design and code, fewer surprises over time.

Why work with me

I have been programming since 1999, delivered more than 300 projects and work as an external developer with about 30 agencies, from Rome and remotely. I use Tailwind with Nuxt and Vue for fast, consistent sites that are easy to evolve, and translate designs into components that stay faithful on every screen.

If you have a project to set up properly, get in touch: in a call of about 20 minutes we work out the technical foundation it needs. The service is in Website development.

Frequently asked questions

If you write everything inline on the page, yes. The right way is to extract components: the class combination of a button or card lives in a single component, reused everywhere. The markup stays readable and styling has a single source of truth.

Configuration is written directly in CSS with @theme, tokens become native CSS variables, the engine is faster and Vite integration happens through a dedicated plugin. Less JavaScript configuration, fewer tools to maintain.

In a custom theme, yes, with a build that scans the templates. It makes no sense on a site built with a page builder or ready-made theme, where styling is already decided elsewhere.

No: only the classes actually used in the templates end up in the published file. Stylesheet weight barely grows even as the site grows.

  • #tailwind css
  • #css
  • #design system
  • #nuxt
  • #performance

More articles

// Contact

A project, a problem or just a question?

Agency, business or professional: choose how you'd rather talk to me. I reply within one working day, no strings attached.