Plugins: Official & Custom
Plugins: Official & Custom
Tailwind CSS plugins extend the framework with new utilities, components, and functionality. The Tailwind team provides several official plugins for common use cases, and you can create custom plugins to add project-specific utilities.
In this lesson, we'll explore the official Tailwind plugins, learn how to use them, and master creating custom plugins to extend Tailwind exactly how you need it.
Official Tailwind Plugins
Tailwind maintains several official plugins that add specialized functionality. Let's explore each one:
1. @tailwindcss/typography (Prose Plugin)
The typography plugin provides beautiful default styles for content you don't control, like markdown or CMS content:
Installing Typography Plugin
# Install the plugin
npm install @tailwindcss/typography
# Or with yarn
yarn add @tailwindcss/typography
Configure in tailwind.config.js
// tailwind.config.js
module.exports = {
theme: {
// ...
},
plugins: [
require('@tailwindcss/typography'),
],
}
Now you can use the prose class on any container with user-generated content:
Using the Prose Class
<article class="prose lg:prose-xl">
<h1>Article Title</h1>
<p>This is a paragraph with <a href="#">a link</a> and <strong>bold text</strong>.</p>
<h2>Subheading</h2>
<p>More content here...</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
<blockquote>
A beautiful blockquote with proper styling
</blockquote>
</article>
<!-- With dark mode support -->
<article class="prose dark:prose-invert lg:prose-xl">
<!-- Content automatically styled for dark mode -->
</article>
<!-- Different color themes -->
<article class="prose prose-slate"><!-- Slate theme --></article>
<article class="prose prose-gray"><!-- Gray theme --></article>
<article class="prose prose-zinc"><!-- Zinc theme --></article>
<article class="prose prose-stone"><!-- Stone theme --></article>
<!-- Size modifiers -->
<article class="prose prose-sm"><!-- Small --></article>
<article class="prose prose-base"><!-- Default --></article>
<article class="prose prose-lg"><!-- Large --></article>
<article class="prose prose-xl"><!-- Extra large --></article>
<article class="prose prose-2xl"><!-- 2X large --></article>
module.exports = {
theme: {
extend: {
typography: {
DEFAULT: {
css: {
color: '#333',
a: {
color: '#3182ce',
'&:hover': {
color: '#2c5282',
},
},
},
},
},
},
},
}
2. @tailwindcss/forms
The forms plugin provides beautiful default styles for form elements:
Installing Forms Plugin
# Install
npm install @tailwindcss/forms
# Configure
// tailwind.config.js
module.exports = {
plugins: [
require('@tailwindcss/forms'),
],
}
With the plugin installed, all form elements get beautiful default styles:
Styled Form Elements
<form class="space-y-4">
<!-- Text input - automatically styled -->
<input type="text" placeholder="Email address" />
<!-- Textarea - automatically styled -->
<textarea rows="4" placeholder="Your message"></textarea>
<!-- Select - automatically styled -->
<select>
<option>Option 1</option>
<option>Option 2</option>
</select>
<!-- Checkbox - automatically styled -->
<input type="checkbox" />
<!-- Radio - automatically styled -->
<input type="radio" name="option" />
<!-- File input - automatically styled -->
<input type="file" />
</form>
<!-- Override with utility classes -->
<input type="text" class="rounded-full border-purple-500" />
3. @tailwindcss/aspect-ratio
The aspect-ratio plugin helps you maintain aspect ratios for responsive elements:
Installing Aspect Ratio Plugin
# Install
npm install @tailwindcss/aspect-ratio
# Configure
module.exports = {
plugins: [
require('@tailwindcss/aspect-ratio'),
],
}
Using Aspect Ratios
<!-- 16:9 aspect ratio video embed -->
<div class="aspect-w-16 aspect-h-9">
<iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"
class="w-full h-full"></iframe>
</div>
<!-- Square (1:1) -->
<div class="aspect-w-1 aspect-h-1">
<img src="profile.jpg" class="object-cover" />
</div>
<!-- 4:3 aspect ratio -->
<div class="aspect-w-4 aspect-h-3">
<img src="photo.jpg" class="object-cover" />
</div>
<!-- 21:9 ultra-wide -->
<div class="aspect-w-21 aspect-h-9">
<video src="video.mp4" class="object-cover"></video>
</div>
aspect-ratio CSS. You can use Tailwind's aspect-square, aspect-video, or arbitrary values like aspect-[4/3] without the plugin.
4. @tailwindcss/container-queries
Container queries allow you to style elements based on their container size, not viewport size:
Installing Container Queries Plugin
# Install
npm install @tailwindcss/container-queries
# Configure
module.exports = {
plugins: [
require('@tailwindcss/container-queries'),
],
}
Using Container Queries
<!-- Make parent a container -->
<div class="@container">
<!-- Style child based on container width, not viewport -->
<div class="@sm:text-lg @md:text-xl @lg:text-2xl">
This text size responds to container width
</div>
</div>
<!-- Named containers -->
<div class="@container/sidebar">
<div class="@lg/sidebar:flex-row flex-col">
Layout changes based on sidebar container
</div>
</div>
<!-- Practical card example -->
<div class="@container">
<div class="flex @md:flex-row flex-col gap-4">
<img src="image.jpg" class="@md:w-48 w-full" />
<div class="flex-1">
<h3 class="@md:text-xl text-lg">Card Title</h3>
<p class="@sm:block hidden">Description visible in larger containers</p>
</div>
</div>
</div>
Creating Custom Plugins
Custom plugins let you extend Tailwind with your own utilities, components, and variants. There are several plugin API methods:
Plugin API Methods
- addUtilities(): Add new utility classes
- addComponents(): Add new component classes
- addBase(): Add base styles (like normalize.css)
- matchUtilities(): Add utilities that support arbitrary values
- addVariant(): Add custom variants (like hover:, focus:)
1. Adding Simple Utilities
Basic Custom Plugin
// tailwind.config.js
const plugin = require('tailwindcss/plugin');
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
const newUtilities = {
'.text-shadow': {
textShadow: '2px 2px 4px rgba(0, 0, 0, 0.1)',
},
'.text-shadow-md': {
textShadow: '4px 4px 8px rgba(0, 0, 0, 0.15)',
},
'.text-shadow-lg': {
textShadow: '6px 6px 12px rgba(0, 0, 0, 0.2)',
},
'.text-shadow-none': {
textShadow: 'none',
},
};
addUtilities(newUtilities);
}),
],
};
// Usage in HTML
<h1 class="text-shadow-md">Text with shadow</h1>
2. Adding Utilities with Variants
Plugin with Responsive and Hover Support
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
addUtilities({
'.rotate-y-180': {
transform: 'rotateY(180deg)',
},
'.rotate-x-180': {
transform: 'rotateX(180deg)',
},
'.preserve-3d': {
transformStyle: 'preserve-3d',
},
'.perspective-1000': {
perspective: '1000px',
},
'.backface-hidden': {
backfaceVisibility: 'hidden',
},
});
}),
],
};
// Usage with variants
<div class="hover:rotate-y-180 transition-transform duration-500
preserve-3d backface-hidden">
Flip card on hover
</div>
3. Adding Components
Component Plugin
module.exports = {
plugins: [
plugin(function({ addComponents, theme }) {
const buttons = {
'.btn': {
padding: `${theme('spacing.2')} ${theme('spacing.4')}`,
borderRadius: theme('borderRadius.md'),
fontWeight: theme('fontWeight.semibold'),
transition: 'all 0.2s',
'&:focus': {
outline: 'none',
boxShadow: theme('boxShadow.md'),
},
},
'.btn-primary': {
backgroundColor: theme('colors.blue.500'),
color: theme('colors.white'),
'&:hover': {
backgroundColor: theme('colors.blue.600'),
},
},
'.btn-secondary': {
backgroundColor: theme('colors.gray.200'),
color: theme('colors.gray.800'),
'&:hover': {
backgroundColor: theme('colors.gray.300'),
},
},
};
addComponents(buttons);
}),
],
};
// Usage
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
4. Adding Base Styles
Base Styles Plugin
module.exports = {
plugins: [
plugin(function({ addBase, theme }) {
addBase({
'h1': {
fontSize: theme('fontSize.4xl'),
fontWeight: theme('fontWeight.bold'),
marginBottom: theme('spacing.4'),
},
'h2': {
fontSize: theme('fontSize.3xl'),
fontWeight: theme('fontWeight.semibold'),
marginBottom: theme('spacing.3'),
},
'a': {
color: theme('colors.blue.600'),
textDecoration: 'underline',
'&:hover': {
color: theme('colors.blue.800'),
},
},
'code': {
backgroundColor: theme('colors.gray.100'),
padding: `${theme('spacing.1')} ${theme('spacing.2')}`,
borderRadius: theme('borderRadius.md'),
fontSize: theme('fontSize.sm'),
},
});
}),
],
};
5. Match Utilities (Arbitrary Values)
This is the most powerful plugin type—it creates utilities that support arbitrary values:
Match Utilities Plugin
const plugin = require('tailwindcss/plugin');
module.exports = {
plugins: [
plugin(function({ matchUtilities, theme }) {
// Create 'text-shadow-[value]' utility
matchUtilities(
{
'text-shadow': (value) => ({
textShadow: value,
}),
},
{ values: theme('textShadow') }
);
// Create 'grid-cols-auto-[value]' utility
matchUtilities(
{
'grid-cols-auto': (value) => ({
gridTemplateColumns: `repeat(auto-fit, minmax(${value}, 1fr))`,
}),
}
);
}),
],
theme: {
extend: {
textShadow: {
sm: '1px 1px 2px rgba(0, 0, 0, 0.1)',
DEFAULT: '2px 2px 4px rgba(0, 0, 0, 0.15)',
lg: '4px 4px 8px rgba(0, 0, 0, 0.2)',
},
},
},
};
// Usage
<h1 class="text-shadow">Default shadow</h1>
<h1 class="text-shadow-lg">Large shadow</h1>
<h1 class="text-shadow-[3px_3px_6px_rgba(0,0,0,0.3)]">Arbitrary shadow</h1>
<div class="grid grid-cols-auto-[250px]">
Auto-fit grid with 250px minimum
</div>
6. Custom Variants
Adding Custom Variants
module.exports = {
plugins: [
plugin(function({ addVariant }) {
// Add 'hocus' variant (hover OR focus)
addVariant('hocus', ['&:hover', '&:focus']);
// Add 'not-first' variant
addVariant('not-first', '&:not(:first-child)');
// Add 'not-last' variant
addVariant('not-last', '&:not(:last-child)');
// Add 'optional' variant (for optional form fields)
addVariant('optional', '&:optional');
// Add 'group-focus-within' variant
addVariant('group-focus-within', ':merge(.group):focus-within &');
// Add children variant
addVariant('children', '& > *');
}),
],
};
// Usage
<button class="hocus:bg-blue-600">Hover or focus</button>
<li class="not-first:border-t">List item with top border (except first)</li>
<input class="optional:border-gray-300">Optional field</input>
<div class="group">
<input />
<div class="group-focus-within:visible invisible">Help text</div>
</div>
Real-World Plugin Example
Let's create a comprehensive plugin with multiple features:
Complete Custom Plugin
// tailwind.config.js
const plugin = require('tailwindcss/plugin');
module.exports = {
plugins: [
plugin(function({ addUtilities, addComponents, addBase, matchUtilities, theme, addVariant }) {
// 1. Add base styles
addBase({
'::selection': {
backgroundColor: theme('colors.blue.200'),
color: theme('colors.blue.900'),
},
});
// 2. Add custom utilities
addUtilities({
'.scrollbar-hide': {
'-ms-overflow-style': 'none',
'scrollbar-width': 'none',
'&::-webkit-scrollbar': {
display: 'none',
},
},
'.scrollbar-default': {
'-ms-overflow-style': 'auto',
'scrollbar-width': 'auto',
'&::-webkit-scrollbar': {
display: 'block',
},
},
});
// 3. Add components
addComponents({
'.card': {
backgroundColor: theme('colors.white'),
borderRadius: theme('borderRadius.lg'),
padding: theme('spacing.6'),
boxShadow: theme('boxShadow.lg'),
},
'.badge': {
display: 'inline-flex',
alignItems: 'center',
padding: `${theme('spacing.1')} ${theme('spacing.2')}`,
borderRadius: theme('borderRadius.full'),
fontSize: theme('fontSize.xs'),
fontWeight: theme('fontWeight.medium'),
},
});
// 4. Add matchUtilities for arbitrary values
matchUtilities(
{
'animate-delay': (value) => ({
animationDelay: value,
}),
},
{ values: theme('transitionDelay') }
);
// 5. Add custom variants
addVariant('not-last', '&:not(:last-child)');
addVariant('hocus', ['&:hover', '&:focus']);
}),
],
theme: {
extend: {
transitionDelay: {
'100': '100ms',
'200': '200ms',
'300': '300ms',
},
},
},
};
Plugin Options
You can create configurable plugins that accept options:
Plugin with Options
// custom-plugin.js
const plugin = require('tailwindcss/plugin');
module.exports = plugin.withOptions(
function (options = {}) {
return function ({ addUtilities }) {
const { prefix = 'custom' } = options;
addUtilities({
[`.${prefix}-utility`]: {
// Your styles
},
});
};
},
function (options = {}) {
return {
theme: {
extend: {
// Theme extensions based on options
},
},
};
}
);
// Usage in tailwind.config.js
module.exports = {
plugins: [
require('./custom-plugin')({ prefix: 'my' }),
],
};
Practice Exercise
Task: Create a custom plugin for common patterns:
- Add a
.glasscomponent class for glassmorphism effect (backdrop blur, semi-transparent background, border) - Create
.gradient-textutility for gradient text with webkit background clip - Add
.text-outline-[width]matchUtilities for text stroke - Create a custom
group-openvariant for details/summary elements - Add
.animate-slide-in-[direction]utilities (top, bottom, left, right) - Test all utilities with responsive and dark mode variants
Challenge Exercise
Advanced Task: Build a complete utility plugin system:
- Create a plugin that adds scrollbar styling utilities (width, color, track, thumb)
- Add selection text styling utilities (background, color, text-decoration)
- Create advanced animation utilities: pause, play-state, fill-mode, iteration-count
- Add filter utilities for SVG filters (blur, brightness, contrast, drop-shadow)
- Create geometric shape utilities using clip-path (circle, triangle, hexagon, arrow)
- Add custom grid utilities: auto-fit, auto-fill with arbitrary min/max values
- Create a
.debugcomponent that adds outlines to all children (for layout debugging) - Make all utilities work with arbitrary values, responsive variants, and dark mode
- Package as a reusable npm plugin with documentation
Summary
In this lesson, you've learned:
- Official Tailwind plugins: typography, forms, aspect-ratio, container-queries
- How to install and configure plugins
- Plugin API methods: addUtilities, addComponents, addBase, matchUtilities, addVariant
- Creating simple utility plugins
- Building component plugins that use theme values
- Adding base styles for HTML elements
- Creating match utilities that support arbitrary values
- Adding custom variants for special selectors
- Building configurable plugins with options
- Best practices for plugin development
Plugins are the key to making Tailwind truly yours. Whether you're using official plugins for common patterns or creating custom ones for project-specific needs, you now have the tools to extend Tailwind infinitely. Congratulations on completing this comprehensive Tailwind CSS course!