Master Tailwind CSS plugins and extensions to supercharge your development workflow. Learn to use official plugins, discover community extensions, and create your own custom plugins.
Tailwind CSS's plugin system is one of its most powerful features, allowing you to extend the framework with custom utilities, components, and functionality. Whether you're using official plugins like @tailwindcss/forms and @tailwindcss/typography, integrating community extensions, or building your own custom plugins, understanding the plugin ecosystem will dramatically enhance your development capabilities.
In this lesson, you'll explore the complete plugin landscape—from installation and configuration to creating sophisticated custom plugins that solve your specific design challenges.
Official Plugins provide battle-tested solutions for common patterns like form styling and rich typography. Community Plugins offer specialized functionality for animations, gradients, and more. Custom Plugins let you codify your design system into reusable utilities.
Let's dive into the world of Tailwind plugins and learn how to leverage this powerful extension system.
Tailwind Labs maintains several official plugins that extend the framework's core functionality. These plugins are production-ready, well-documented, and actively maintained.
Provides a basic reset for form styles that makes form elements easy to override with utilities.
Installation:
1npm install -D @tailwindcss/formsConfiguration:
1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('@tailwindcss/forms'),
5 ],
6}Usage:
1<!-- Forms plugin provides better default styles -->
2<input type="text" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
3
4<select class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
5 <option>Option 1</option>
6 <option>Option 2</option>
7</select>
8
9<textarea class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"></textarea>Strategy Option:
1// Use 'class' strategy to only apply styles via classes
2plugins: [
3 require('@tailwindcss/forms')({
4 strategy: 'class', // only apply to elements with .form-* classes
5 }),
6]Adds a prose class for beautiful typographic defaults for rich text content like markdown or CMS content.
Installation:
1npm install -D @tailwindcss/typographyConfiguration:
1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('@tailwindcss/typography'),
5 ],
6}Usage:
1<!-- Prose classes style all child elements beautifully -->
2<article class="prose lg:prose-xl">
3 <h1>Blog Post Title</h1>
4 <p>This paragraph will have beautiful typography...</p>
5 <ul>
6 <li>List items are styled</li>
7 <li>Automatically</li>
8 </ul>
9 <blockquote>
10 Quotes look professional
11 </blockquote>
12</article>
13
14<!-- Dark mode support -->
15<article class="prose dark:prose-invert">
16 <!-- Content automatically adapts to dark mode -->
17</article>
18
19<!-- Color themes -->
20<article class="prose prose-slate"> <!-- slate theme -->
21<article class="prose prose-zinc"> <!-- zinc theme -->
22<article class="prose prose-stone"> <!-- stone theme -->Prose Modifiers:
| Modifier | Description |
|----------|-------------|
| prose-sm | Small text (14px base) |
| prose-base | Base text (16px base) - default |
| prose-lg | Large text (18px base) |
| prose-xl | Extra large (20px base) |
| prose-2xl | 2X large (24px base) |
Adds utilities for controlling aspect ratios (deprecated in Tailwind v3.1+, use native aspect-ratio utilities instead).
Installation:
1npm install -D @tailwindcss/aspect-ratioUsage (legacy):
1<div class="aspect-w-16 aspect-h-9">
2 <iframe src="https://www.youtube.com/embed/..." frameborder="0"></iframe>
3</div>Modern Alternative (Tailwind v3.1+):
1<!-- Use native aspect-ratio utilities -->
2<div class="aspect-video">
3 <iframe src="https://www.youtube.com/embed/..." frameborder="0"></iframe>
4</div>
5
6<div class="aspect-square">
7 <img src="profile.jpg" alt="Profile" class="object-cover">
8</div>
9
10<div class="aspect-[4/3]"> <!-- custom ratio -->
11 <img src="photo.jpg" alt="Photo">
12</div>Adds utilities for visually truncating text after a fixed number of lines (now built into Tailwind v3.3+).
Modern Usage (Tailwind v3.3+):
1<p class="line-clamp-3">
2 This text will be truncated after 3 lines with an ellipsis...
3</p>
4
5<p class="line-clamp-2">
6 Two lines maximum...
7</p>
8
9<p class="line-clamp-none">
10 Remove line clamping
11</p>Adds container query utilities for responsive design based on parent container size.
Installation:
1npm install -D @tailwindcss/container-queriesConfiguration:
1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('@tailwindcss/container-queries'),
5 ],
6}Usage:
1<div class="@container">
2 <div class="@lg:grid @lg:grid-cols-2">
3 <!-- Layout changes based on container size, not viewport -->
4 <div>Content 1</div>
5 <div>Content 2</div>
6 </div>
7</div>The Tailwind ecosystem includes many high-quality community plugins that add specialized functionality.
Adds animation utilities inspired by Animate.css.
Installation:
1npm install -D tailwindcss-animateConfiguration:
1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('tailwindcss-animate'),
5 ],
6}Usage:
1<div class="animate-fade-in">Fades in</div>
2<div class="animate-slide-in-left">Slides from left</div>
3<div class="animate-bounce-in">Bounces in</div>Previously popular form plugin, now superseded by official forms plugin.
Adds utilities for styling scrollbars.
Installation:
1npm install -D tailwind-scrollbarUsage:
1<div class="overflow-y-auto scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-100">
2 <!-- Scrollable content with styled scrollbar -->
3</div>Adds beautiful gradient utilities (note: Tailwind v3+ has native gradient support).
Shows the current breakpoint in development (helpful for responsive debugging).
Installation:
1npm install -D tailwindcss-debug-screensConfiguration:
1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('tailwindcss-debug-screens'),
5 ],
6}Usage:
1<body class="debug-screens">
2 <!-- Shows breakpoint indicator in corner during development -->
3</body>Resources:
Evaluation Criteria:
Custom plugins let you add your own utilities, components, and variants to Tailwind. Understanding plugin development unlocks unlimited customization potential.
A Tailwind plugin is a function that receives a helper object with methods for registering new styles.
Basic Plugin Template:
1// tailwind.config.js
2const plugin = require('tailwindcss/plugin')
3
4module.exports = {
5 plugins: [
6 plugin(function({ addUtilities, addComponents, e, config }) {
7 // Your plugin code here
8 })
9 ],
10}| Helper | Purpose | Example |
|--------|---------|---------|
| addUtilities() | Add new utility classes | Custom spacing, transforms |
| addComponents() | Add new component classes | Buttons, cards, badges |
| addVariant() | Add new variants | Custom states, selectors |
| addBase() | Add base styles | CSS resets, global styles |
| theme() | Access theme values | Colors, spacing, fonts |
| config() | Access config values | Any config setting |
| e() | Escape class names | Handle special characters |
| variants() | Get variant config | Check enabled variants |
Example 1: Text Utilities
1const plugin = require('tailwindcss/plugin')
2
3module.exports = {
4 plugins: [
5 plugin(function({ addUtilities }) {
6 const newUtilities = {
7 '.text-shadow': {
8 textShadow: '0 2px 4px rgba(0,0,0,0.10)',
9 },
10 '.text-shadow-md': {
11 textShadow: '0 4px 8px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08)',
12 },
13 '.text-shadow-lg': {
14 textShadow: '0 15px 30px rgba(0,0,0,0.11), 0 5px 15px rgba(0,0,0,0.08)',
15 },
16 '.text-shadow-none': {
17 textShadow: 'none',
18 },
19 }
20
21 addUtilities(newUtilities)
22 })
23 ],
24}Usage:
1<h1 class="text-4xl text-shadow-lg">Heading with shadow</h1>
2<p class="text-shadow">Paragraph with subtle shadow</p>Example 2: Responsive Utilities
1plugin(function({ addUtilities }) {
2 const newUtilities = {
3 '.rotate-y-180': {
4 transform: 'rotateY(180deg)',
5 },
6 '.preserve-3d': {
7 transformStyle: 'preserve-3d',
8 },
9 '.perspective': {
10 perspective: '1000px',
11 },
12 '.backface-hidden': {
13 backfaceVisibility: 'hidden',
14 },
15 }
16
17 addUtilities(newUtilities)
18})Usage:
1<div class="perspective">
2 <div class="preserve-3d rotate-y-180">
3 <div class="backface-hidden">Front</div>
4 <div class="backface-hidden rotate-y-180">Back</div>
5 </div>
6</div>Components are pre-styled combinations of utilities.
1plugin(function({ addComponents }) {
2 const buttons = {
3 '.btn': {
4 padding: '.5rem 1rem',
5 borderRadius: '.25rem',
6 fontWeight: '600',
7 cursor: 'pointer',
8 transition: 'all 0.2s',
9 },
10 '.btn-primary': {
11 backgroundColor: '#3b82f6',
12 color: '#ffffff',
13 '&:hover': {
14 backgroundColor: '#2563eb',
15 },
16 },
17 '.btn-secondary': {
18 backgroundColor: '#6b7280',
19 color: '#ffffff',
20 '&:hover': {
21 backgroundColor: '#4b5563',
22 },
23 },
24 }
25
26 addComponents(buttons)
27})Usage:
1<button class="btn btn-primary">Primary Button</button>
2<button class="btn btn-secondary">Secondary Button</button>Access your theme configuration within plugins.
1plugin(function({ addUtilities, theme }) {
2 const colors = theme('colors')
3 const spacing = theme('spacing')
4
5 const glowUtilities = Object.keys(colors).reduce((acc, colorName) => {
6 if (typeof colors[colorName] === 'object') {
7 acc[`.glow-${colorName}`] = {
8 boxShadow: `0 0 20px ${colors[colorName]['500']}`,
9 }
10 }
11 return acc
12 }, {})
13
14 addUtilities(glowUtilities)
15})Usage:
1<div class="glow-blue">Glows blue</div>
2<div class="glow-red">Glows red</div>Advanced plugin techniques enable sophisticated customization and reusable design system components.
Variants modify when utilities are applied (like hover, focus, dark).
Example 1: Custom State Variant
1plugin(function({ addVariant }) {
2 // Add a 'hocus' variant that applies on both hover and focus
3 addVariant('hocus', ['&:hover', '&:focus'])
4
5 // Add a 'group-hocus' variant
6 addVariant('group-hocus', [':merge(.group):hover &', ':merge(.group):focus &'])
7})Usage:
1<div class="hocus:bg-blue-500">Applies on hover or focus</div>
2
3<div class="group">
4 <div class="group-hocus:text-blue-500">Changes when group is hovered or focused</div>
5</div>Example 2: Child Selector Variant
1plugin(function({ addVariant }) {
2 // Add variant for styling direct children
3 addVariant('children', '& > *')
4
5 // Add variant for styling all descendants
6 addVariant('descendants', '& *')
7})Usage:
1<div class="children:bg-gray-100">
2 <p>This paragraph gets gray background</p>
3 <p>This one too</p>
4</div>Example 3: Data Attribute Variant
1plugin(function({ addVariant, e }) {
2 addVariant('open', ({ modifySelectors, separator }) => {
3 modifySelectors(({ className }) => {
4 return `.${e(`open${separator}${className}`)}[data-state="open"]`
5 })
6 })
7})Usage:
1<div data-state="open" class="open:bg-blue-500">
2 Shows blue background when data-state is "open"
3</div>Create plugins that accept configuration options.
1const plugin = require('tailwindcss/plugin')
2
3const myPlugin = plugin.withOptions(
4 function (options = {}) {
5 return function({ addUtilities, theme }) {
6 const prefix = options.prefix || 'custom'
7 const sizes = options.sizes || theme('spacing')
8
9 const utilities = Object.keys(sizes).reduce((acc, key) => {
10 acc[`.${prefix}-w-${key}`] = { width: sizes[key] }
11 acc[`.${prefix}-h-${key}`] = { height: sizes[key] }
12 return acc
13 }, {})
14
15 addUtilities(utilities)
16 }
17 },
18 function (options = {}) {
19 return {
20 theme: {
21 customSizes: options.sizes || {},
22 },
23 }
24 }
25)
26
27module.exports = {
28 plugins: [
29 myPlugin({
30 prefix: 'my',
31 sizes: {
32 'xs': '20rem',
33 'sm': '24rem',
34 'md': '28rem',
35 }
36 })
37 ],
38}File Structure:
1my-tailwind-plugin/
2├── index.js
3├── package.json
4└── README.mdindex.js:
1const plugin = require('tailwindcss/plugin')
2
3module.exports = plugin(function({ addUtilities, theme, e }) {
4 // Your plugin code
5 const newUtilities = {
6 '.skew-10deg': {
7 transform: 'skewY(-10deg)',
8 },
9 '.skew-15deg': {
10 transform: 'skewY(-15deg)',
11 },
12 }
13
14 addUtilities(newUtilities)
15})package.json:
1{
2 "name": "tailwindcss-skew",
3 "version": "1.0.0",
4 "description": "Adds skew utilities to Tailwind CSS",
5 "main": "index.js",
6 "keywords": ["tailwindcss", "plugin", "skew"],
7 "peerDependencies": {
8 "tailwindcss": ">=3.0.0"
9 }
10}Publishing:
1npm publishUsage in Projects:
1npm install -D tailwindcss-skew1// tailwind.config.js
2module.exports = {
3 plugins: [
4 require('tailwindcss-skew'),
5 ],
6}1const plugin = require('tailwindcss/plugin')
2
3const cardPlugin = plugin(function({ addComponents, theme }) {
4 const cards = {
5 '.card': {
6 backgroundColor: theme('colors.white'),
7 borderRadius: theme('borderRadius.lg'),
8 padding: theme('spacing.6'),
9 boxShadow: theme('boxShadow.md'),
10 },
11 '.card-header': {
12 fontSize: theme('fontSize.xl'),
13 fontWeight: theme('fontWeight.bold'),
14 marginBottom: theme('spacing.4'),
15 },
16 '.card-body': {
17 color: theme('colors.gray.700'),
18 fontSize: theme('fontSize.base'),
19 },
20 '.card-footer': {
21 marginTop: theme('spacing.4'),
22 paddingTop: theme('spacing.4'),
23 borderTop: `1px solid ${theme('colors.gray.200')}`,
24 },
25 '.card-bordered': {
26 border: `1px solid ${theme('colors.gray.200')}`,
27 boxShadow: 'none',
28 },
29 '.card-hover': {
30 transition: 'all 0.3s',
31 '&:hover': {
32 transform: 'translateY(-4px)',
33 boxShadow: theme('boxShadow.xl'),
34 },
35 },
36 }
37
38 addComponents(cards)
39})
40
41module.exports = {
42 plugins: [cardPlugin],
43}Usage:
1<div class="card card-hover">
2 <div class="card-header">Card Title</div>
3 <div class="card-body">Card content goes here...</div>
4 <div class="card-footer">
5 <button class="btn btn-primary">Action</button>
6 </div>
7</div>Follow these best practices to create maintainable, performant, and user-friendly Tailwind plugins.
Use Clear, Descriptive Names:
1// ✅ Good - clear purpose
2'.text-shadow'
3'.btn-primary'
4'.card-bordered'
5
6// ❌ Bad - unclear purpose
7'.ts'
8'.bp'
9'.cb'Follow Tailwind's Patterns:
1// ✅ Good - follows Tailwind patterns
2'.glow-sm'
3'.glow-md'
4'.glow-lg'
5
6// ❌ Bad - inconsistent with Tailwind
7'.smallGlow'
8'.mediumGlow'
9'.largeGlow'**Use matchUtilities for Dynamic Values:**
1// ✅ Good - supports arbitrary values like text-shadow-[2px]
2matchUtilities(
3 {
4 'text-shadow': (value) => ({
5 textShadow: value,
6 }),
7 },
8 { values: theme('textShadow') }
9)
10
11// ❌ Bad - generates all utilities upfront
12const utilities = {}
13theme('textShadow').forEach((value, key) => {
14 utilities[`.text-shadow-${key}`] = { textShadow: value }
15})
16addUtilities(utilities)Limit Generated Classes:
1// ✅ Good - only essential utilities
2addUtilities({
3 '.rotate-y-180': { transform: 'rotateY(180deg)' },
4 '.rotate-y-90': { transform: 'rotateY(90deg)' },
5})
6
7// ❌ Bad - generates too many variants
8for (let i = 0; i <= 360; i++) {
9 utilities[`.rotate-y-${i}`] = { transform: `rotateY(${i}deg)` }
10}Use Theme Values:
1// ✅ Good - respects user's theme
2plugin(function({ addUtilities, theme }) {
3 addUtilities({
4 '.custom-shadow': {
5 boxShadow: theme('boxShadow.lg'),
6 },
7 })
8})
9
10// ❌ Bad - hardcoded values
11plugin(function({ addUtilities }) {
12 addUtilities({
13 '.custom-shadow': {
14 boxShadow: '0 10px 15px rgba(0,0,0,0.1)',
15 },
16 })
17})Provide Configuration Options:
1const plugin = require('tailwindcss/plugin')
2
3module.exports = plugin.withOptions(
4 function(options = {}) {
5 return function({ addUtilities }) {
6 const className = options.className || 'custom-utility'
7 addUtilities({
8 [`.${className}`]: {
9 // ... utility styles
10 },
11 })
12 }
13 }
14)Provide Clear Documentation:
1# My Tailwind Plugin
2
3## Installation
4npm install -D my-tailwind-plugin
1
2## Configuration
3// tailwind.config.js
module.exports = {
plugins: [
require('my-tailwind-plugin')({
// options
}),
],
}
1
2## Usage
3
4### Basic Example
5<div class="custom-utility">Content</div>
1
2### With Variants
3<div class="hover:custom-utility">Content</div>
1
2## 5. TypeScript Support
3
4**Provide Type Definitions:**
5// index.d.ts
import { PluginCreator } from 'tailwindcss/types/config'
interface PluginOptions {
className?: string
sizes?: Record<string, string>
}
declare const plugin: PluginCreator<PluginOptions>
export default plugin
1
2## 6. Testing
3
4**Test Your Plugin:**
5// __tests__/plugin.test.js
const postcss = require('postcss')
const tailwindcss = require('tailwindcss')
const myPlugin = require('../index')
test('generates custom utilities', async () => {
const result = await postcss(
tailwindcss({
content: [{ raw: '<div class="text-shadow"></div>' }],
plugins: [myPlugin],
})
).process('@tailwind utilities', { from: undefined })
expect(result.css).toContain('.text-shadow')
})
1
2## 7. Versioning and Compatibility
3
4**Specify Tailwind Version Compatibility:**
5{
"peerDependencies": {
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
}
}
1
2**Handle Breaking Changes:**
3// Check Tailwind version and adapt
const tailwindVersion = require('tailwindcss/package.json').version
const [major] = tailwindVersion.split('.')
if (major >= 3) {
// Use Tailwind v3 APIs
} else {
// Use Tailwind v2 APIs
}
1
2## 8. Production Optimization
3
4**Only Add Necessary Styles:**
5// ✅ Good - only adds if used
addUtilities(utilities, ['responsive', 'hover'])
// ❌ Bad - always adds all variants
addUtilities(utilities, Object.keys(variants()))
1
2**Use JIT-Compatible Patterns:**
3// ✅ JIT-compatible
matchUtilities(
{ 'custom': (value) => ({ property: value }) },
{ values: theme('customValues') }
)
1 Let's build complete, production-ready plugins for common use cases.
1const plugin = require('tailwindcss/plugin')
2
3const glassmorphism = plugin(function({ addUtilities, theme, e }) {
4 const glassUtilities = {
5 '.glass': {
6 background: 'rgba(255, 255, 255, 0.1)',
7 backdropFilter: 'blur(10px)',
8 borderRadius: theme('borderRadius.lg'),
9 border: '1px solid rgba(255, 255, 255, 0.2)',
10 },
11 '.glass-dark': {
12 background: 'rgba(0, 0, 0, 0.1)',
13 backdropFilter: 'blur(10px)',
14 borderRadius: theme('borderRadius.lg'),
15 border: '1px solid rgba(255, 255, 255, 0.1)',
16 },
17 '.glass-blur-sm': {
18 backdropFilter: 'blur(4px)',
19 },
20 '.glass-blur-md': {
21 backdropFilter: 'blur(10px)',
22 },
23 '.glass-blur-lg': {
24 backdropFilter: 'blur(20px)',
25 },
26 '.glass-blur-xl': {
27 backdropFilter: 'blur(40px)',
28 },
29 }
30
31 addUtilities(glassUtilities)
32})
33
34module.exports = glassmorphismUsage:
1<div class="glass p-6">
2 <h2>Glassmorphism Card</h2>
3 <p>Beautiful frosted glass effect</p>
4</div>
5
6<div class="glass-dark glass-blur-xl p-6">
7 <h2>Dark Glass with Heavy Blur</h2>
8</div>1const plugin = require('tailwindcss/plugin')
2
3const gradientText = plugin(function({ addUtilities, theme }) {
4 const colors = theme('colors')
5
6 const gradients = {
7 '.text-gradient': {
8 '-webkit-background-clip': 'text',
9 '-webkit-text-fill-color': 'transparent',
10 'background-clip': 'text',
11 },
12 '.text-gradient-primary': {
13 backgroundImage: `linear-gradient(to right, ${colors.blue[500]}, ${colors.purple[500]})`,
14 },
15 '.text-gradient-sunset': {
16 backgroundImage: `linear-gradient(to right, ${colors.orange[500]}, ${colors.pink[500]})`,
17 },
18 '.text-gradient-ocean': {
19 backgroundImage: `linear-gradient(to right, ${colors.cyan[500]}, ${colors.blue[600]})`,
20 },
21 '.text-gradient-forest': {
22 backgroundImage: `linear-gradient(to right, ${colors.green[500]}, ${colors.emerald[600]})`,
23 },
24 }
25
26 addUtilities(gradients)
27})
28
29module.exports = gradientTextUsage:
1<h1 class="text-gradient text-gradient-primary text-6xl font-bold">
2 Gradient Heading
3</h1>
4
5<p class="text-gradient text-gradient-sunset text-2xl">
6 Sunset gradient text
7</p>1const plugin = require('tailwindcss/plugin')
2
3const scrollbar = plugin(function({ addUtilities, theme, e }) {
4 const scrollbarUtilities = {
5 '.scrollbar-thin': {
6 '&::-webkit-scrollbar': {
7 width: '8px',
8 height: '8px',
9 },
10 },
11 '.scrollbar-medium': {
12 '&::-webkit-scrollbar': {
13 width: '12px',
14 height: '12px',
15 },
16 },
17 '.scrollbar-thick': {
18 '&::-webkit-scrollbar': {
19 width: '16px',
20 height: '16px',
21 },
22 },
23 '.scrollbar-thumb-rounded': {
24 '&::-webkit-scrollbar-thumb': {
25 borderRadius: theme('borderRadius.full'),
26 },
27 },
28 }
29
30 // Generate scrollbar color utilities
31 const colors = theme('colors')
32 Object.keys(colors).forEach(colorName => {
33 if (typeof colors[colorName] === 'object') {
34 Object.keys(colors[colorName]).forEach(shade => {
35 const className = `.${e(`scrollbar-thumb-${colorName}-${shade}`)}`
36 scrollbarUtilities[className] = {
37 '&::-webkit-scrollbar-thumb': {
38 backgroundColor: colors[colorName][shade],
39 },
40 }
41
42 const trackClassName = `.${e(`scrollbar-track-${colorName}-${shade}`)}`
43 scrollbarUtilities[trackClassName] = {
44 '&::-webkit-scrollbar-track': {
45 backgroundColor: colors[colorName][shade],
46 },
47 }
48 })
49 }
50 })
51
52 addUtilities(scrollbarUtilities)
53})
54
55module.exports = scrollbarUsage:
1<div class="h-64 overflow-y-auto scrollbar-thin scrollbar-thumb-blue-500 scrollbar-track-gray-100 scrollbar-thumb-rounded">
2 <!-- Long content that scrolls -->
3</div>1const plugin = require('tailwindcss/plugin')
2
3const animationDelay = plugin(function({ matchUtilities, theme }) {
4 matchUtilities(
5 {
6 'animate-delay': (value) => ({
7 animationDelay: value,
8 }),
9 },
10 {
11 values: theme('transitionDelay'),
12 }
13 )
14})
15
16module.exports = {
17 theme: {
18 extend: {
19 transitionDelay: {
20 '0': '0ms',
21 '75': '75ms',
22 '100': '100ms',
23 '150': '150ms',
24 '200': '200ms',
25 '300': '300ms',
26 '500': '500ms',
27 '700': '700ms',
28 '1000': '1000ms',
29 },
30 },
31 },
32 plugins: [animationDelay],
33}Usage:
1<div class="animate-fade-in animate-delay-100">Appears after 100ms</div>
2<div class="animate-fade-in animate-delay-300">Appears after 300ms</div>
3<div class="animate-fade-in animate-delay-500">Appears after 500ms</div>Create a comprehensive plugin that adds a design system with custom utilities, components, and variants.
1// tailwind.config.js
2const plugin = require('tailwindcss/plugin')
3
4// Custom Design System Plugin
5const designSystemPlugin = plugin(function({ addUtilities, addComponents, addVariant, theme, e }) {
6
7 // 1. Custom Utilities - Text Shadows
8 const textShadows = {
9 '.text-shadow-sm': {
10 textShadow: '0 1px 2px rgba(0, 0, 0, 0.1)',
11 },
12 '.text-shadow': {
13 textShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
14 },
15 '.text-shadow-md': {
16 textShadow: '0 4px 8px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08)',
17 },
18 '.text-shadow-lg': {
19 textShadow: '0 15px 30px rgba(0, 0, 0, 0.11), 0 5px 15px rgba(0, 0, 0, 0.08)',
20 },
21 '.text-shadow-none': {
22 textShadow: 'none',
23 },
24 }
25
26 // 2. Component Classes - Buttons
27 const buttonComponents = {
28 '.btn': {
29 padding: theme('spacing.2') + ' ' + theme('spacing.4'),
30 borderRadius: theme('borderRadius.md'),
31 fontWeight: theme('fontWeight.semibold'),
32 fontSize: theme('fontSize.sm'),
33 transition: 'all 0.2s',
34 cursor: 'pointer',
35 display: 'inline-block',
36 textAlign: 'center',
37 },
38 '.btn-sm': {
39 padding: theme('spacing.1') + ' ' + theme('spacing.3'),
40 fontSize: theme('fontSize.xs'),
41 },
42 '.btn-lg': {
43 padding: theme('spacing.3') + ' ' + theme('spacing.6'),
44 fontSize: theme('fontSize.base'),
45 },
46 '.btn-primary': {
47 backgroundColor: theme('colors.blue.500'),
48 color: theme('colors.white'),
49 '&:hover': {
50 backgroundColor: theme('colors.blue.600'),
51 },
52 },
53 '.btn-secondary': {
54 backgroundColor: theme('colors.gray.500'),
55 color: theme('colors.white'),
56 '&:hover': {
57 backgroundColor: theme('colors.gray.600'),
58 },
59 },
60 }
61
62 // 3. Custom Variant - "hocus" (hover + focus)
63 addVariant('hocus', ['&:hover', '&:focus'])
64
65 // Add utilities and components
66 addUtilities(textShadows)
67 addComponents(buttonComponents)
68})
69
70module.exports = {
71 theme: {
72 extend: {},
73 },
74 plugins: [
75 require('@tailwindcss/forms'),
76 require('@tailwindcss/typography'),
77 designSystemPlugin,
78 ],
79}This example demonstrates a complete plugin that adds:
1. Custom Utilities (Text Shadows):
2. Component Classes (Button System):
.btn class with core styles.btn-sm, .btn-lg).btn-primary, .btn-secondary)3. Custom Variant:
Usage:
1<!-- Text shadows -->
2<h1 class="text-shadow-lg">Heading with large shadow</h1>
3
4<!-- Button components -->
5<button class="btn btn-primary">Primary Button</button>
6<button class="btn btn-secondary btn-lg">Large Secondary</button>
7
8<!-- Custom variant -->
9<a href="#" class="hocus:text-blue-500">Link changes on hover or focus</a>This pattern can be extended with additional utilities, components, and variants to create a complete design system.
Now that you understand Tailwind plugins, you're ready to:
Challenge: Create a custom plugin that adds utilities for your brand's color system, including color variants, shadows, and text gradients. Publish it to npm!
Your progress is saved in this browser, on this device only.