This guide covers creating custom TailwindCSS plugins to extend functionality.
A plugin is a function that receives a PluginAPI object:
import plugin from 'tailwindcss/plugin';
const myPlugin = plugin(function ({ addUtilities, addComponents, addVariant }) {
// Add utilities
addUtilities({
'.custom-utility': {
display: 'flex',
justifyContent: 'center',
},
});
// Add components
addComponents({
'.card': {
padding: '1rem',
borderRadius: '0.5rem',
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
},
});
// Add variants
addVariant('optional', '&:optional');
});Create configurable plugins using plugin.withOptions():
interface MyPluginOptions {
className?: string;
respectPrefix?: boolean;
}
const myPlugin = plugin.withOptions<MyPluginOptions>(
function (options = {}) {
return function ({ addUtilities, prefix }) {
const className = options.className || 'custom';
const name = options.respectPrefix ? prefix(className) : className;
addUtilities({
[`.${name}`]: {
display: 'flex',
justifyContent: 'center',
},
});
};
}
);
// Use with options
export default {
plugins: [
myPlugin({
className: 'centered',
respectPrefix: true,
}),
],
};Create utilities that accept values using matchUtilities():
plugin(function ({ matchUtilities, theme }) {
matchUtilities(
{
'scroll-m': (value) => ({
'scroll-margin': value,
}),
},
{
values: theme('spacing'),
}
);
});Create variants that accept values using matchVariant():
plugin(function ({ matchVariant }) {
matchVariant('supports', (value) => `@supports (${value})`);
matchVariant('nth', (value) => `&:nth-child(${value})`);
});Access theme values in plugins:
plugin(function ({ addUtilities, theme }) {
const colors = theme('colors');
const spacing = theme('spacing.4', '1rem'); // with default
addUtilities({
'.custom': {
padding: spacing,
color: colors.blue[500],
},
});
});Plugins can provide additional configuration:
const buttonPlugin = plugin(
function ({ addComponents, theme }) {
addComponents({
'.btn': {
padding: theme('spacing.4'),
borderRadius: theme('borderRadius.md'),
},
});
},
{
theme: {
extend: {
colors: {
'btn-primary': '#3b82f6',
},
},
},
}
);import plugin from 'tailwindcss/plugin';
interface AnimationOptions {
prefix?: string;
}
const animationPlugin = plugin.withOptions<AnimationOptions>(
function (options = {}) {
return function ({ addUtilities, matchUtilities, addVariant, theme }) {
const prefix = options.prefix || '';
// Static utilities
addUtilities({
[`.${prefix}animate-spin-slow`]: {
animation: 'spin 3s linear infinite',
},
});
// Functional utilities
matchUtilities(
{
[`${prefix}animation-delay`]: (value) => ({
'animation-delay': value,
}),
},
{
values: theme('transitionDelay'),
}
);
// Variants
addVariant('motion-safe', '@media (prefers-reduced-motion: no-preference)');
};
},
function (options = {}) {
return {
theme: {
extend: {
transitionDelay: {
0: '0ms',
100: '100ms',
},
},
},
};
}
);
export default animationPlugin;