Safelisting in TailwindCSS v4
The safelisting feature in TailwindCSS ensures critical utility classes are included in your final CSS bundle even if they aren't directly referenced in your markup. Here's how the safelist approach evolved in Tailwind v4.
Problem Statement
In TailwindCSS v3, you could safely include classes using JS configuration:
// tailwind.config.js (v3)
export default {
safelist: [
{
pattern: /grid-cols-+/,
variants: ["sm", "md", "lg", "xl"],
},
],
}
However, TailwindCSS v4 removed the JS-based safelist
property. Attempting to use it results in errors since Tailwind now favors CSS-first configuration. Without safelisting, developers had to implement workarounds like:
- Creating dummy elements with needed classes
- Using
@apply
in CSS files to force inclusion - Adding unused class names to markup
Solution: @source inline()
Directive (v4.1+)
Tailwind 4.1 introduced the @source inline()
directive as a safe-list replacement. Paste this in your CSS file where Tailwind is imported:
@import "tailwindcss";
@source inline('{sm:,md:,lg:,xl:,}grid-cols-{{1..12}}');
Key Syntax Features
Variants Prefix variants followed by comma for base + variants:
{sm:,}
generates:grid-cols-*
(base)sm:grid-cols-*
Numerical ranges with
{{start..end}}
:grid-cols-{{1..12}}
generates classes fromgrid-cols-1
togrid-cols-12
Multiple values/patterns Comma-separate lists:
p{,,x,y,t,b,l,r}-{1..10}
WARNING
Always include a trailing comma after variants to generate base classes. This:{sm:,}
includes both base and sm variants.
Whereas {sm:}
would generate only sm variants.
Advanced Examples
- Multiple variants with dynamic values:
@source inline('{hover:,focus:}bg-blue-{50,100,200,400,800}');
- Complex ranges with explicit values:
@source inline('{md:,lg:}w-{1/2,1/3,full,{300..600..50}}');
- Combined utilities:
@source inline('{m,p}{t,b}-{0,4,8,12}');
Performance Consideration
Excessive safe-listing significantly increases CSS bundle size. Only include essential classes. Test your compiled CSS with Tailwind Playground to verify output.
Pre-v4.1 Workarounds
Versions ≤4.0.17 don't support safe-listing. If upgrading isn't possible:
Option 1: Generate classes via external file
// generate-classes.js
const fs = require('fs');
const classes = [
'sm:grid-cols-1', 'sm:grid-cols-2', /* ... */, 'xl:grid-cols-12'
];
fs.writeFileSync('safelist.txt', classes.join('\n'));
@import "tailwindcss";
@source "safelist.txt";
Option 2: Force inclusion via theme config (limited)
@import "tailwindcss";
@theme static {
--grid-columns: 12; /* Only affects CSS variables */
}
When to Use Safelisting
Common valid use cases include:
- Dynamic classes from CMS/user-generated content
- Third-party component libraries
- Programmatically generated class names
- Responsive utilities not detectable in static code
TIP
For static sites, prefer Tailwind's static analysis over manual safe-listing. Run npx tailwindcss --watch
with your content files configured.
Additional Resources
- Official Safelisting Documentation
- Tailwind Playground (Test patterns in real-time)
- Source Directive RFC
The @source inline()
directive provides a powerful, CSS-native solution for safe-listing in Tailwind v4.1+. Use it judiciously to optimize your workflow without compromising performance.