CSS vs Tailwind CSS: Which One Should You Use?

08 Aug 2026 2,020 words
Also available in: 🇫🇷 FR

CSS vs Tailwind CSS: Which One Should You Use?

Few frontend debates generate as much heat as the one between hand-written CSS and Tailwind CSS. Both approaches produce working websites, both have passionate defenders, and both can be misused badly. The truth is that the choice is rarely about which technology is "better" in the abstract; it is about the project, the team, and the constraints you actually have. This article compares the two approaches on the dimensions that matter most and gives you a decision framework instead of a one-size-fits-all answer.

Let us be precise about what we are comparing. Hand-written CSS means authoring styles in stylesheet files using classes, IDs, and cascade rules that you name yourself. Tailwind CSS is a utility-first framework that provides a comprehensive set of prebuilt utility classes, each of which applies a single, predictable styling rule, and you compose them directly in your HTML.

The Learning Curve

The first difference people feel is the learning curve, and it cuts in both directions.

With hand-written CSS, you need to learn the language properly: specificity, the cascade, inheritance, box model, flexbox, grid, responsive breakpoints, and media queries. That is a substantial body of knowledge, and most of it never goes away. Even if you later adopt a framework, understanding how the cascade and specificity work is fundamental to debugging any styling issue.

With Tailwind, you do not need to name classes or think much about specificity, because utility classes are designed to have equal specificity and predictable behavior. Instead, you need to learn Tailwind's class vocabulary: flex, items-center, justify-between, p-4, mt-8, text-sm, bg-blue-500. There are hundreds of these, and while the naming is systematic and mostly intuitive, there is a real memorization cost at the start.

Here is the nuance that most comparisons miss: Tailwind is fast to learn but you will spend your first weeks looking things up, while hand-written CSS is slow to learn but the knowledge is transferable to every tool that sits on top of CSS. If you already know CSS well, Tailwind is easy to pick up. If you are learning from zero, you should learn CSS first either way, because Tailwind is a layer on top of it, not a replacement for it.

Naming Things Is Hard

The classic software engineering saying, that there are only two hard things in computer science and naming things is one of them, applies directly here. Every component you style by hand requires you to invent a class name: .card, .card-header, .card-body, .btn-primary. Those names carry meaning, which is great for readability, but they also create coupling: if the design changes and .card-header becomes a footer, the name lies about the content.

Tailwind sidesteps the naming problem by removing your ability to invent names. Instead of writing a name that describes the component, you write the utilities that style it. The trade-off is that the semantic meaning moves out of the HTML class attribute and into the structure of the component itself, so you rely on good component boundaries in your framework to keep the markup meaningful.

For solo developers and small teams, this often feels liberating. For large codebases maintained by many people, the component-naming debate becomes a governance question: if you do not use Tailwind, you need a naming convention, documentation, and discipline to keep hand-written CSS coherent as it grows.

Maintainability and Refactoring

Maintainability is where the two approaches genuinely diverge, and it depends heavily on how your project is structured.

Hand-written CSS scales well when it is organized around semantic classes and follows a methodology like BEM, where blocks, elements, and modifiers are named consistently. The risk is that in large, long-lived projects, hand-written CSS tends to accumulate: dead rules, duplicated selectors, and specificity wars. As more developers add styles, the cascade becomes harder to predict, and the dreaded "!important everywhere" pattern emerges.

Tailwind changes the maintainability equation by moving the style declarations into the markup. The practical consequences are significant. Removing a component no longer requires hunting for its orphaned CSS rules, because the styles live with the component. Renaming or restructuring a component updates its styling at the same time. And because utilities are single-purpose, you rarely need to worry about one rule unexpectedly overriding another.

The cost appears on the other side: markup becomes denser. A simple button that might be <button class="btn"> in hand-written CSS becomes a long string of utilities in Tailwind. This makes the HTML harder to read at a glance, and if you repeat the same utility string across many places, you now have the duplication problem that used to live in CSS, now living in your templates.

This is where component frameworks help enormously. If you use React, Vue, or a similar framework, a Tailwind class string appears once in the component definition and gets reused everywhere the component is used. That solves the duplication concern almost completely, which is why Tailwind is so popular in component-driven projects.

Performance and Bundle Size

Performance is an area where modern Tailwind has closed most of the historical gap, but the details still matter.

Tailwind's JIT compiler generates only the CSS for the classes you actually use, so a production build contains just the utilities present in your source files. A large hand-written stylesheet with many unused rules can easily be bigger than a Tailwind output. Conversely, if your project uses only a handful of custom styles, Tailwind's minimum output, even purged, may be larger than a tiny hand-written sheet that does exactly the same job.

There is also the developer experience angle: Tailwind's generated CSS is highly repetitive, because each utility class appears once with its full declaration. Minification helps, but utility CSS is structurally more verbose than a hand-written sheet that groups rules under shared selectors. For most real projects the difference is a few kilobytes, which rarely matters, but it is worth knowing when you are optimizing aggressively.

Whichever approach you choose, the tools that keep CSS small are the same. A minifier that removes whitespace and comments reliably, like the CSS minifier on this site, trims every build, and removing unused styles matters far more than the framework choice.

Responsiveness and Complex Layouts

For responsive design, both approaches work, but they express it differently.

Hand-written CSS uses media queries in a stylesheet, which keeps all the responsive rules for a component in one place. You see the base styles and the tablet and desktop overrides together, which can be easier to reason about for complex components.

Tailwind expresses responsiveness through breakpoint prefixes on individual utilities: md:flex, lg:justify-between, xl:grid-cols-3. This is convenient because you change a single element in its markup without editing a separate file, and it handles the common mobile-first pattern cleanly. The trade-off is that a complex responsive component's HTML becomes harder to read, because breakpoint logic is scattered across the class list.

For genuinely complex layouts, like a dense dashboard with unusual grids, some developers find that hand-written CSS with named classes and media queries reads better, while others find Tailwind's composability faster to iterate. This is a matter of preference and team style more than an objective technical difference.

The Ecosystem and Tooling

Tailwind brings a tooling chain: a build step, PostCSS integration, and configuration files for theme tokens, plugins, and variants. That setup has a cost, but it also gives you a consistent design-token system, where colors, spacing, fonts, and breakpoints are defined once in configuration and used everywhere. Teams that adopt it usually report that enforcing design consistency becomes easier.

Hand-written CSS has no mandatory tooling, which makes it attractive for small sites, static pages, and projects that want minimal build complexity. You can achieve the same design-token consistency with CSS custom properties (variables), and many projects do exactly that. The difference is that Tailwind's system is built-in and opinionated, while CSS variables require you to build your own discipline around them.

If you already have a hand-written CSS codebase and want to migrate incrementally, there are tools that help. A CSS to Tailwind converter can translate existing rules into utility classes, and utilities like a Tailwind class explorer help you find the right class when you are learning the vocabulary.

Team Workflow and Onboarding

The choice between CSS and Tailwind has a big effect on how teams collaborate.

Hand-written CSS rewards experience with the cascade and specificity. A new developer joining a hand-written CSS codebase faces the task of understanding the naming conventions, the file organization, and the subtle rules that make the styles work. The learning material is the codebase itself, and mistakes tend to surface as visual bugs that are hard to attribute.

Tailwind reduces the surface area a new developer needs to understand, because the styling rules are visible next to the markup and follow a predictable pattern. Reviews become simpler: a change shows its class changes inline, and there is little hidden cascade state to reason about. The downside is that the team must accept the utility-class aesthetic, which not everyone likes, and the memorization of class names is a real onboarding cost for people new to Tailwind.

There is also the question of designers. In a hand-written CSS project, designers and developers often negotiate through a design system with named tokens and component classes. In a Tailwind project, the design tokens are configured in the framework, and designers who want to control styles directly must learn the utility vocabulary. Neither is wrong, but the collaboration model is different.

Performance Tuning and Custom Designs

When a project needs highly custom, unusual visual effects, hand-written CSS is often the more direct tool. Exotic animations, creative use of pseudo-elements, and intricate layout tricks can be written in plain CSS without fighting against a framework's opinionated structure. Tailwind can express most of these too, through arbitrary value syntax and custom variants, but the path is less obvious and you occasionally need to drop into a custom CSS block anyway.

For more conventional designs, the opposite is true. Standard buttons, cards, navbars, forms, and responsive grids are faster to build in Tailwind because the utilities map directly to the patterns you need. The framework accelerates exactly the boring, high-frequency work that makes up most of a typical product's UI.

Making the Decision

Instead of a universal winner, here is a decision framework you can apply to your project.

Choose hand-written CSS when: you are building a small static site, you want zero build complexity, your team deeply understands the cascade and wants full control, or your design relies on unusual, highly custom styling that would fight a utility framework.

Choose Tailwind CSS when: you are building a component-driven application in React or Vue, your team wants fast iteration and consistency without maintaining a design system by hand, you are starting a new project and want opinionated constraints, or you have multiple developers who need styling to follow a predictable pattern.

Choose both, deliberately, when: your project has a design-system layer that stays in hand-written CSS while the component layer uses utilities, or you have a legacy codebase where you introduce Tailwind incrementally for new features. This hybrid is more common in practice than the purity of the online debate suggests.

A Practical Checklist

If you are still unsure, run through these questions. If you answer yes to most of the Tailwind column, its benefits will outweigh its costs for you.

  • Do you build components with React, Vue, or another framework?
  • Do you value consistent design tokens enforced by configuration?
  • Does your team prefer seeing styles next to markup during review?
  • Do you ship new UI frequently and want fast iteration?
  • Is removing dead styles automatically worth more than keeping HTML terse?

If you are leaning toward hand-written CSS, make sure you have the discipline in place: a naming convention, a file organization strategy, a purge-and-minify step with tools like the CSS minifier, and a culture of deleting dead rules. The framework will not save you from a messy process, whether you write CSS by hand or not.


About this article

A thorough, practical comparison of hand-written CSS and Tailwind CSS: learning curve, maintainability, performance, team workflows, and when each approach wins.


Related Articles


Related Tools