Why Developers Are Migrating from Tailwind CSS to Structured Vanilla CSS
AI News

Why Developers Are Migrating from Tailwind CSS to Structured Vanilla CSS

4 min
5/17/2026
cssfrontendweb-developmenttailwind-css

From Utility-First to Semantic Structure

Eight years after her enthusiastic embrace of Tailwind CSS, developer Julia Evans is charting a new course. In a recent blog post, she details a week-long migration of several sites away from the utility-first framework toward semantic HTML and vanilla CSS. Her journey reflects a broader maturation among developers who, having learned from such frameworks, now seek greater control and expressiveness.

Evans credits Tailwind for providing crucial structure during a time when her CSS skills were less developed. It offered systems for reset styles, color palettes, and font scales, preventing chaos. However, she now finds its constraints limiting and its reliance on build systems cumbersome for her projects.

The migration was driven by several factors. Tailwind has evolved to require a build system, which Evans preferred to avoid, leading to large, static CSS files. She also found herself mixing Tailwind with vanilla CSS, creating maintenance headaches. Ultimately, a desire for more semantic HTML and the freedom to use modern, native CSS features spurred the change.

Building a Structured CSS Architecture

Evans's new approach involves constructing a deliberate, multi-layered CSS architecture. She started by copying Tailwind's Preflight reset, acknowledging her dependency on conventions like universal `box-sizing: border-box`. This forms a stable foundation upon which she layers her own systems.

The core of her architecture is a component-based model, inspired by JavaScript frameworks but implemented purely in CSS. Each visual component gets a unique class and its own CSS file. The goal is isolation: editing one component's styles should not break another. This is enforced by convention, using nested selectors within each component's class.

"The idea is that each 'component' has a unique class," Evans writes. "The CSS for one component never overrides the CSS for any other component." This modularity makes reasoning about styling significantly easier, confining changes to specific, manageable files.

continue reading below...

Implementing Design Systems and Utilities

Beyond components, Evans establishes shared systems for consistency. She maintains a centralized `colors.css` file with CSS custom properties (variables) for her palette, ensuring all colors are defined in one place. For typography, she adopts Tailwind's font scale but implements it with CSS variables.

This replaces the framework's shorthand classes like `text-lg` with more explicit, yet still systematic, declarations like `font-size: var(--size-lg);`. She also retains a small set of utility classes for cross-cutting concerns, such as `.sr-only` for screen readers, but keeps this section minimal and stable.

For base styles that apply site-wide, Evans is cautious. She starts with almost nothing—currently just a section layout rule and a link color—and plans to move styles from components into the base layer only as clear patterns emerge. This bottom-up approach prevents premature over-architecting.

Rethinking Layouts and Responsive Design

A significant shift is in handling spacing and responsive design. Moving away from Tailwind's haphazard padding/margin utilities, Evans aims for principled spacing controlled by outer layout components. She employs selectors like the "owl selector" (`* + *`) to manage space between children systematically.

Perhaps the most profound change is her approach to responsive layouts. Instead of Tailwind's breakpoint-driven media queries (`md:text-xl`), she is exploring the power of CSS Grid. Features like `repeat(auto-fit, minmax(...))` allow for fluid, column-based layouts that adapt without explicit breakpoints.

She also highlights `grid-template-areas` as a powerful, declarative layout tool unavailable within Tailwind's utility paradigm. This exploration into native CSS capabilities represents a key advantage of moving away from a framework: the ability to leverage the full, evolving power of the web platform.

Simplifying the Toolchain and Looking Ahead

The build process is notably simplified. Modern CSS features like native `@import` and nested selectors allow Evans to develop without any build step. For production, she optionally uses `esbuild`, a fast and simple bundler she appreciates for being a static binary and based on web standards.

Evans's reflection underscores that this migration is not a rejection of Tailwind's value but an evolution. The framework served as an excellent teacher, imparting design system principles. Now, she selectively re-implements those principles while gaining the flexibility to use emerging CSS features like `@layer`, `@scope`, container queries, and subgrid.

Her experience mirrors a growing sentiment: as developers' CSS skills deepen and the language itself becomes more powerful, the trade-offs of a strict utility framework shift. The desire for semantic markup, reduced toolchain complexity, and unbounded creativity is leading many to re-embrace vanilla CSS with a new, more structured perspective.