How to make a safelist
in TailwindCSS v4?
As of now tailwind v4 preferable configuration is to use CSS. Not a .config.js
anymore. But even if I use the JS-based configuration, the safelist
property is already disabled in it and can no longer be used from v4 onwards.
In v3 in a file tailwind.config.js
we could do:
export default {
safelist: [
{
pattern: /grid-cols-+/,
variants: ["sm", "md", "lg", "xl"],
},
],
}
Now my workaround is to use a dummy-styled, invisible html or combinations of CSS styles with @apply sm:grid-cols-1 sm:grid-cols-2 lg:grid-cols-1
... etc. Unfortunately this is what my UI and user options are done.
Have they dropped this feature? Can this be done "easly" in the TailwindCSS v4?
TLDR: The v3 safelist mentioned in the question can be written as follows starting from v4.1.
Values can be written comma-separated within curly braces. In v3, grid-cols
ranged from 1 to 12; from v4 onwards, it goes up to infinity. Including an infinite number of values in the compiled CSS would be madness, as it would drastically increase the size of the compiled CSS; so from 1 to 12, it would look like this:
@source inline('{sm:,md:,lg:,xl:,}grid-cols-{1,2,3,4,5,6,7,8,9,10,11,12}');
Note: Since there are variants, a comma indicates that we also want the plain
class name version. So, request grid-cols-{1..12}
even without a variant. If we don't add a comma after sm, md, lg, or xl
, then the plain
version won't be included in the compiled CSS, only the sm, md, lg, and xl
variants will be.
A new syntax has been introduced that makes it easy to list numbers. This uses another pair of curly braces, where you specify the start and end points, and as a third value, the step size. For example, {100..900..50}
means that you want every number from 100 to 900 in steps of 50; i.e., 100, 150, 200... 850, 900
.
@source inline('{sm:,md:,lg:,xl:,}grid-cols-{{1..12..1}}');
When requesting a range, if the third value is omitted, the list is automatically interpreted with a step of 1; so this is also sufficient:
@source inline('{sm:,md:,lg:,xl:,}grid-cols-{{1..12}}');
This can actually be made more complex, since I can request fixed numbers as well as different ranges. For example, I can request the value 1 explicitly, and then ask for values from 10 to 90 in steps of 5, and so on:
@source inline('{sm:,md:,lg:,xl:,}grid-cols-{1,{10..90..5}}');
With this feature, now have the ability to include critically important classes in the compiled CSS using a syntax similar to the safelist
property from v3.
tailwindlabs/tailwindcss
PR #17147:@source inline(…)
@source not inline(…)
- GitHub@source inline()
- TailwindCSS v4 Docssafelist
property - TailwindCSS v3 DocsWith @source
, can provide file paths by default; specifying files where TailwindCSS classes are used. This instructs TailwindCSS to scan those files, collect all the class names have used, and include them in the compiled CSS.
With @source inline
, instead of specifying a file path, can directly pass in specific class names. It's as if had used them in a file, but even without actual usage, request that they be included in the compiled CSS. For the class names provided here, a special syntax is available—already familiar from v3—that allows us to list variants and specify variable parts of the class names.
Here's an example from the PR to illustrate the inline syntax:
@source inline('underline');
For more complex syntax:
@source inline('{hover:,}bg-red-{50,{100..900..100},950}');
In this example, request both the plain
class names and the hover:
variant versions. Also ask for the bg-red
colors: 50, followed by every 100-level value from 100 to 900, and finally 950.
Each class name must be passed through a separate @source inline
. So, for example, as mentioned earlier, the underline
and bg-red
class names should be declared as two separate @source inline
statements to ensure they are included in the compiled CSS, regardless of whether they are actually used anywhere.
For example, you can also generate the pt-
, pb-
, pl-
, pr-
, px-
, and py-
classes with a single @source inline
declaration in a similar way from 1 to 10 (stepping by 1 when the third value is omitted):
@source inline("p{x,y,t,b,l,r}-{1..10}");
Note: Here, I didn't add a comma at the end of the x,y,...,l,r
list; but if I did, it would also generate the p-1
, p-2
classes.
But we can make this even more complex by declaring margin
and padding
together:
@source inline("{m,p}{x,y,t,b,l,r}-{1..10}");
Note: You can see that I didn't add a comma at the end of the m,p
list to avoid declaring meaningless plain x-1
, y-2
, ... classes.
I'd like to point out that excessive use of the safelist
is not a good idea. Handle the safelist
with great care and only use it in absolutely necessary cases in order to reduce the size of your compiled CSS. A bloated compiled CSS will worsen the loading experience and demand more data usage from every visitor.
Safelists and blocklists — can't force Tailwind to generate certain classes or prevent it from generating other classes yet.
As of version 4.0, there is no built-in option for using the safelist feature available in v3. However, as others have suggested, if you can reference the required class names in some form, TailwindCSS will include them in the build.