DEV Community

Cover image for Day 7: How to Create Reusable Tailwind CSS Components Using @apply
Ruqaiya Beguwala
Ruqaiya Beguwala

Posted on • Originally published at Medium

Day 7: How to Create Reusable Tailwind CSS Components Using @apply

Welcome to Day 7 of 15 Days of Tailwind Tips

As you continue building with Tailwind CSS, you’ll quickly notice patterns forming in your code — repeated classes for buttons, cards, inputs, and more. Repetition isn't necessarily bad, but it can make your markup harder to maintain.

This is where the @apply directive comes in.

Tailwind gives you the flexibility of utility classes in your HTML, but also provides @apply to consolidate styles into reusable custom classes when needed — especially helpful in larger projects or component libraries.

Let’s walk through how @apply works and how to use it effectively.


Getting Started with @apply

The @apply directive is used inside your CSS (or PostCSS) to include Tailwind utility classes into a custom class. This makes your components cleaner and more maintainable.

Here’s how you can build a custom button style:

/* styles.css */ .btn-primary { @apply px-4 py-2 rounded bg-blue-600 text-white font-medium hover:bg-blue-700 transition; } 
Enter fullscreen mode Exit fullscreen mode

Then in your HTML:

<button class="btn-primary">Submit</button> 
Enter fullscreen mode Exit fullscreen mode

Now every .btn-primary button will have consistent styling — and you only define it once.


What You Need to Use @apply

To use @apply, you need to ensure:

  1. You're using Tailwind with a proper build tool (like Vite, PostCSS, or a framework like Next.js or Laravel).
  2. You define your custom styles in a CSS/SCSS file that Tailwind processes (usually inside ./src or wherever your CSS entry lives).
  3. The file is included in your Tailwind config via content.

Real-World Example: Input Field

Instead of repeating styles across every input, you can define a clean, reusable input class:

.input { @apply border border-gray-300 rounded px-4 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500; } 
Enter fullscreen mode Exit fullscreen mode
<input type="text" class="input" placeholder="Your email" /> 
Enter fullscreen mode Exit fullscreen mode

This makes your forms cleaner, easier to manage, and consistent across components.


Component Naming Tips

When using @apply, follow a naming convention that matches your design system or team’s style:

Purpose Suggested Class Name
Primary button .btn-primary
Outline button .btn-outline
Card container .card
Input field .input, .input-lg
Header wrapper .page-header

Stick to semantic, role-based names — avoid naming based on visual appearance alone (like .blue-button).


Summary: When to Use @apply

Use @apply when:

  • You have repeated utility patterns across your HTML
  • You want to follow a design system or shared component library
  • You’re building larger-scale projects where consistency and readability matter
  • You need to separate structure (HTML) from styling logic

Avoid @apply for one-off elements or very simple styles — inline utilities are usually more readable in those cases.


Advanced Tips & Tricks

Here are a few practical ideas and patterns to help you level up with @apply:


1. Create Variants Using Utility + Custom Classes

Use modifier classes for different button states:

.btn { @apply px-4 py-2 rounded font-medium transition; } .btn-primary { @apply bg-blue-600 text-white hover:bg-blue-700; } .btn-danger { @apply bg-red-600 text-white hover:bg-red-700; } 
Enter fullscreen mode Exit fullscreen mode

2. Combine @apply with Responsive Utilities

Tailwind supports responsive utilities inside @apply when using Tailwind v3+:

.card { @apply p-4 sm:p-6 md:p-8 bg-white rounded shadow; } 
Enter fullscreen mode Exit fullscreen mode

3. Use With Dark Mode

You can use dark mode utilities inside @apply just like in HTML:

.card { @apply bg-white text-gray-900 dark:bg-gray-800 dark:text-white; } 
Enter fullscreen mode Exit fullscreen mode

4. Extract Layout Components

Create layout-related classes like .section, .wrapper, or .grid-2:

.wrapper { @apply max-w-4xl mx-auto px-4; } .grid-2 { @apply grid grid-cols-1 md:grid-cols-2 gap-6; } 
Enter fullscreen mode Exit fullscreen mode

5. Mix with Custom Properties

You can mix utility classes with custom variables or design tokens:

.btn { @apply px-4 py-2 rounded; background-color: var(--btn-color); } 
Enter fullscreen mode Exit fullscreen mode

6. Use in Component Frameworks (React, Vue, etc.)

Define your styles with @apply and import them as modules in React:

<button className="btn-primary">Buy Now</button> 
Enter fullscreen mode Exit fullscreen mode

Keeps components clean and avoids bloating your JSX with repetitive classes.


Conclusion

@apply is a powerful feature in Tailwind CSS that bridges the gap between utility-first styling and traditional component-based CSS. It’s especially useful in larger projects where consistency, scalability, and readability become important.

While Tailwind encourages utility classes in HTML, you don’t need to sacrifice maintainability or clarity. Use @apply strategically to extract common patterns, build reusable components, and keep your codebase clean as it grows.

In tomorrow’s post, we’ll move into UI polish — learning how to create elegant custom shadows and depth for your components using Tailwind’s built-in utilities.


Top comments (0)