The @apply directive in TailwindCSS allows developers to reuse TailwindCSS utility classes in CSS files, combining multiple utility classes into a reusable class. This is a powerful feature but needs to be used carefully.
@apply Directive Basics
Basic Syntax
css/* Use @apply in CSS files */ .btn { @apply bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded; } .card { @apply bg-white rounded-lg shadow-md p-6; }
Usage in HTML
html<!-- Use defined classes --> <button class="btn">Click button</button> <div class="card"> <h3>Card title</h3> <p>Card content</p> </div>
Use Cases
1. Creating Reusable Components
css/* Button component */ .btn { @apply px-4 py-2 rounded font-bold transition-colors duration-200; } .btn-primary { @apply bg-blue-500 hover:bg-blue-600 text-white; } .btn-secondary { @apply bg-gray-200 hover:bg-gray-300 text-gray-800; } .btn-danger { @apply bg-red-500 hover:bg-red-600 text-white; }
2. Form Element Styles
css/* Input styles */ .input { @apply w-full px-4 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent; } .input-error { @apply border-red-500 focus:ring-red-500; } /* Textarea */ .textarea { @apply w-full px-4 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none; }
3. Layout Containers
css/* Container styles */ .container { @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8; } /* Grid layout */ .grid-container { @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6; } /* Flex layout */ .flex-center { @apply flex items-center justify-center; }
Advanced Usage
1. Responsive @apply
css/* Responsive button */ .responsive-btn { @apply px-4 py-2 text-sm; @apply md:px-6 md:py-3 md:text-base; @apply lg:px-8 lg:py-4 lg:text-lg; } /* Responsive grid */ .responsive-grid { @apply grid grid-cols-1 gap-4; @apply md:grid-cols-2 md:gap-6; @apply lg:grid-cols-3 lg:gap-8; }
2. State Variants
css/* Button with states */ .interactive-btn { @apply bg-blue-500 hover:bg-blue-600 active:bg-blue-700 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2; } /* Form input states */ .form-input { @apply border-gray-300 focus:border-blue-500 focus:ring-blue-500 disabled:bg-gray-100 disabled:cursor-not-allowed; }
3. Conditional Combinations
css/* Conditional styles */ .conditional-card { @apply bg-white rounded-lg shadow-md p-6; } .conditional-card.active { @apply ring-2 ring-blue-500; } .conditional-card.disabled { @apply opacity-50 cursor-not-allowed; }
Combining with CSS Variables
1. Using CSS Variables
css/* Define CSS variables */ :root { --primary-color: #3b82f6; --secondary-color: #10b981; --spacing-md: 1rem; } /* Use in @apply */ .variable-btn { @apply px-[var(--spacing-md)] py-[var(--spacing-md)] rounded; background-color: var(--primary-color); } .variable-btn:hover { background-color: var(--secondary-color); }
2. Dynamic Theming
css/* Theme variables */ [data-theme="dark"] { --bg-color: #1f2937; --text-color: #f9fafb; } [data-theme="light"] { --bg-color: #ffffff; --text-color: #1f2937; } /* Themed component */ .themed-card { @apply rounded-lg shadow-md p-6; background-color: var(--bg-color); color: var(--text-color); }
Best Practices
1. When to Use @apply
Suitable for @apply:
- Complex style combinations used in multiple places
- Creating semantic component class names
- Reducing repetitive utility classes
- Improving code readability
Not suitable for @apply:
- Styles used only once
- Simple style combinations
- Styles that need frequent adjustments
2. Naming Conventions
css/* Use semantic naming */ /* ✅ Recommended */ .user-avatar { @apply w-12 h-12 rounded-full object-cover; } .nav-link { @apply px-4 py-2 hover:bg-gray-100 transition-colors; } /* ❌ Not recommended */ .style1 { @apply w-12 h-12 rounded-full; } .blue-button { @apply bg-blue-500 text-white; }
3. Keep It Simple
css/* ✅ Recommended: Simple combination */ .card { @apply bg-white rounded-lg shadow-md p-6; } /* ❌ Not recommended: Overusing @apply */ .card { @apply bg-white; @apply rounded-lg; @apply shadow-md; @apply p-6; @apply hover:shadow-lg; @apply transition-shadow; @apply duration-300; }
Common Issues
1. Choosing Between @apply and Inline Classes
html<!-- Use @apply defined class --> <button class="btn-primary">Button</button> <!-- Use utility classes directly --> <button class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded"> Button </button>
Selection Principles:
- Repeatedly used styles → Use @apply
- One-time styles → Use utility classes
- Need semantic naming → Use @apply
- Rapid prototyping → Use utility classes
2. Performance Impact of @apply
css/* @apply expands to actual CSS at compile time */ .btn { @apply bg-blue-500 hover:bg-blue-600 text-white; } /* After compilation, equivalent to */ .btn { background-color: #3b82f6; } .btn:hover { background-color: #2563eb; } .btn { color: white; }
Performance Considerations:
- @apply itself doesn't affect runtime performance
- Expands to actual CSS rules at compile time
- Overuse may lead to increased CSS file size
- Reasonable use can improve code maintainability
3. Combining with CSS Modules
css/* Use @apply in CSS modules */ .button { @apply px-4 py-2 rounded font-bold transition-colors; } .button--primary { @apply bg-blue-500 hover:bg-blue-600 text-white; } .button--secondary { @apply bg-gray-200 hover:bg-gray-300 text-gray-800; }
Considerations
- Compile-time Expansion: @apply expands at compile time, not dynamically generated at runtime
- Priority Issues: Styles generated by @apply may conflict with directly written CSS
- Maintainability: Overuse of @apply may reduce code readability
- Team Collaboration: Ensure team consensus on @apply usage
- Performance Monitoring: Regularly check generated CSS file size
Summary
The @apply directive is a powerful feature in TailwindCSS that helps developers create reusable style combinations. Proper use of @apply can:
- Improve code readability and maintainability
- Reduce duplicate code
- Create semantic component class names
- Maintain HTML simplicity
But note:
- Don't overuse @apply
- Keep naming semantic
- Ensure team collaboration consistency
- Monitor CSS file size