Search code examples
tailwind-csstailwind-ui

Prevent Tailwind from stripping unused classes - preserve full css


I have a Laravel project with Tailwind and have Webpack configured:

mix.js('resources/js/app.js', 'public/js')
  .postCss('resources/css/app.css', 'public/css', [
      require("tailwindcss"),
  ]);

And this is my Tailwind.config:

const defaultTheme = require("tailwindcss/defaultTheme");
const colors = require("tailwindcss/colors");

module.exports = {
  content: [
    "./resources/**/*.blade.php",
    "./resources/**/*.js",
    "./resources/**/*.vue",
  ],
  theme: {
    extend: {
      fontFamily: {
         sans: ["Rubik", ...defaultTheme.fontFamily.sans],
      },
    },
    colors: {
      transparent: "transparent",
      current: "currentColor",
      black: colors.black,
      white: colors.white,
      gray: colors.gray,
      emerald: colors.emerald,
      brandcolor: {
        50: "#f3d2e4",
        100: "#ff53aa",
        200: "#ff49a0",
        300: "#ff3f96",
        400: "#f8358c",
        500: "#ee2b82",
        600: "#e42178",
        700: "#da176e",
        800: "#d00d64",
        900: "#c6035a",
      },
      blue: {
        50: "#a6ecfd",
        100: "#50d4ff",
        200: "#46caff",
        300: "#3cc0f6",
        400: "#32b6ec",
        500: "#28ace2",
        600: "#1ea2d8",
        700: "#1498ce",
        800: "#0a8ec4",
        900: "#0084ba",
      },
      teal: colors.teal,
      yellow: colors.yellow,
    },
  },
  plugins: [
    require("@tailwindcss/forms"),
    require("@tailwindcss/aspect-ratio"),
    require("@tailwindcss/typography"),
  ],
};

As you can see I changed and add some colors.

When I have this in my code and I compile it:

<div class="bg-brandcolor-600"> 

It works, but when I change it to 800, I have to recompile it.

What do I have to change so the FULL css is compiled with all options available? So i can also do things like:

<div class="bg-{{ $color ?? 'brandcolor' }}-600"> 

And make the color as a variable in my code. And I know, that this is not recommended, but the CSS doesn't have to be small for this project.


Solution

  • You may specify safelist section of config file. More info here

    For example, in your case we need to safelist every brandcolor entry. Pattern accepts regex, so you config may look like

    module.exports = {
        content: [
            './resources/views/**/*.blade.php',
            './resources/js/**/*.js',
        ],
        safelist: [
            {
                pattern: /.-brandcolor-./,
            }
        ],
        theme: {,
            extend: {
                colors: {
                    brandcolor: {
                        50: "#f3d2e4",
                        100: "#ff53aa",
                        200: "#ff49a0",
                        300: "#ff3f96",
                        400: "#f8358c",
                        500: "#ee2b82",
                        600: "#e42178",
                        700: "#da176e",
                        800: "#d00d64",
                        900: "#c6035a",
                    },
                }
            },
        },
    }
    

    This way you may ensure that every possible class which contains -brandcolor- will not be purged. You may specify even better - if you sure you only need background and text color, regex may be like

    module.exports = {
        content: [
            './resources/views/**/*.blade.php',
            './resources/js/**/*.js',
        ],
        safelist: [
            {
                pattern: /(bg|text)-(brandcolor|blue)-./,
            }
            // OR multiple entries - same as above
            {
                pattern: /(bg|text)-blue-./,
            },
            {
                pattern: /(bg|text)-brandcolor-./,
            }
        ],
        // theme config the same... 
    }
    

    You may check it in your blade file

    @foreach ([50, 100, 300, 800] as $brand)
      <div class="bg-brandcolor-{{ $brand }}">
       {{ $brand }}
      </div>
    @endforeach
    

    Alternative way - create any file (for example, safelist.txt) write there any class you want to be not purged and include it at content section. This way you have more control but EVERY class should be included as it is - not regural expression (under the hood it reads class as a string)

    The way Tailwind scans your source code for classes is intentionally very simple — we don’t actually parse or execute any of your code in the language it’s written in, we just use regular expressions to extract every string that could possibly be a class name - link

    module.exports = {
        content: [
            './resources/views/**/*.blade.php',
            './resources/js/**/*.js',
            './safelist.txt',
        ],
        // theme config the same... 
    }
    

    Finally, you may use CDN if you don't care about duplicated styles and optimization

    As an example - add these lines within head tag and you will see brandcolors will be generated inside @foreach loop

    <script src="https://cdn.tailwindcss.com"></script>
        <script>
            tailwind.config = {
                theme: {
                    colors: {
                        brandcolor: {
                            50: "#f3d2e4",
                            100: "#ff53aa",
                            200: "#ff49a0",
                            300: "#ff3f96",
                            400: "#f8358c",
                            500: "#ee2b82",
                            600: "#e42178",
                            700: "#da176e",
                            800: "#d00d64",
                            900: "#c6035a",
                        },
                    }
                }
            }
        </script>
    

    P.S. Before version 3.0 there was an option to disable purge by purge.enabled = false but as Tailwind no more uses PurgeCSS this is not an option anymore. Correct me if I wrong

    EDIT: For Tailwind v3+ you can "disable purge" completely with

    safelist: [
        {
            pattern: /.*/
        }
    ],