@apply & Component Classes

Extract Patterns — Sparingly

@apply & Component Classes

@apply inlines utilities into a custom CSS class, which is useful for markup you cannot edit but easy to overuse.

4 min read Level 2/5 #tailwind#apply#customization
What you'll learn
  • Use @apply to build a reusable component class
  • Recognize when extraction hurts more than it helps
  • Prefer component templates over @apply when you control the markup

@apply copies the declarations of utility classes into a custom class. It is a sharp tool: indispensable in a few situations, counterproductive in many.

Building a Component Class

Compose utilities into a single semantic class:

@import "tailwindcss";

.btn {
  @apply inline-flex items-center rounded-md bg-blue-600
         px-4 py-2 font-medium text-white
         hover:bg-blue-700 focus-visible:ring-2;
}

Now plain <button class="btn"> works anywhere, including HTML you do not generate.

When Extraction Hurts

The trap is rebuilding a component layer that your framework already gives you. If you control the markup, a component is clearer than a CSS class:

<!-- Premature: a .card class that only ever wraps this template -->
<div class="card">...</div>

A React, Astro, or template component co-locates structure and styling and is far easier to evolve than a CSS class you must keep in sync with markup. Extracting too early also fragments the utility model that makes Tailwind fast to work in.

Where @apply Genuinely Wins

Reach for it when you cannot put classes on the element directly:

.prose-custom h2 {
  @apply mt-10 text-2xl font-bold tracking-tight;
}

Form libraries, Markdown and prose overrides, third-party widget markup — anything you do not author. In v4, @apply resolves correctly across @layers, so a component-layer class can apply utility-layer classes without specificity surprises. Use it for markup you do not control; prefer components for markup you do.

Plugins →