'purgecss can't recognize conditional classes

So I'm using TailwindCSS for a WP theme I'm developing.

I ran into an issue in creating the production grade theme files because, from how I understand the problem, purgecss can't recognize conditional classes used on template parts. For example, let's say I created a template part called "business-card.php" where I pass it a variable type (using set_query_var / get_query_var):

page-about.php

set_query_var('type', 'A');
get_template_part('template-parts/content/business', 'card');

set_query_var('type', 'B');
get_template_part('template-parts/content/business', 'card');

businesss-card.php

$type = get_query_var('type')
<div class="<?php echo type == 'A' ? 'text-color-A' : 'text-color-B' ?>">
--- insert some content here ---
</div>

So there will be two divs, one will have a text-color-A class, the other will have a text-color-B, both were created using a config file(rather than included in the base tailwind theme). This is fine in development -- since tailwind does actually create the utility color classes from the config file. But for some reason, when it's in production (i.e. purged & minified), it doesn't have those utility classes -- which were only used in the template part as conditional classes (and not in any other file).



Solution 1:[1]

PurgeCSS is intentionally very naive in the way it looks for classes in your HTML. It doesn't try to parse your HTML and look for class attributes or dynamically execute your JavaScript — it simply looks for any strings in the entire file that match this regular expression:

/[^<>"'`\s]*[^<>"'`\s:]/g

That means that it is important to avoid dynamically creating class strings in your templates with string concatenation, otherwise PurgeCSS won't know to preserve those classes.

So do not use string concatenation to create class names:

<div :class="text-{{ error ? 'red' : 'green' }}-600"></div>

Instead, dynamically select a complete class name:

<div :class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

As long as a class name appears in your template in its entirety, PurgeCSS will not remove it.

See the docs for more details:

Solution 2:[2]

If you are using Tailwind 2.0+ you can configure whitelisted classes that will be ignored by purge CSS directly inside of your tailwind.config.js file.

An example of my own code where I whitelist the class text-ingido-400 can be seen below

  // tailwind.config.js
  module.exports = {
    purge: {
      content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],

      options: {
        safelist: ['text-indigo-400']
      }
    } ,
     darkMode: false, // or 'media' or 'class'
     theme: {
       extend: {},
     },
     variants: {
       extend: {},
     },
     plugins: [],
   }

For more information you can check out the relevant documentation located at: https://tailwindcss.com/docs/optimizing-for-production

Solution 3:[3]

You can use the PurgeCSS whitelist option to add those classes.

const purgecss = new Purgecss({
    //... Your config
    whitelist: ['text-color-A', 'text-color-B', 'etc']
})

Or the whitelistPatterns (Regex match)

whitelistPatterns: [/^text-color/], // All classes starting with text-color

You can find more information here

Solution 4:[4]

If you define your class names in a variable above where you want to use them it works akin to safe listing them in Tailwind or whitelisting them in PurgeCSS, is potentially easier to maintain, and works good in a pinch if you have a small number of possbile dynamic class names.

var classes =`grid-cols-1 grid-cols-2 grid-cols-3 grid-cols-4`
    return (
               <div className={`grid grid-cols-${items['grid-cols']}`}>
                
               </div>
           )

Solution 5:[5]

For some tailwindcss class, you can use inline style instead.

Inline style allow you to use dynamic value, like <div style="padding-left:{indent}rem">.

I think it works in php also. More details can be found here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gino
Solution 3 Enrique Chavez
Solution 4 Greggory Wiley
Solution 5 fsarter