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.
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.