5

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.

kissu
  • 40,416
  • 14
  • 65
  • 133
user1469734
  • 851
  • 14
  • 50
  • 81
  • This is not just "not recommended", this is a no-go to ask your end users to download 5 MB of CSS on their 200$ phones when only 10kB may be enough. Depending of your framework, this may be as simple as having `myCoolColor` as a variable and having it matched to a value in an array (also called a `dictionary`/`associative array` in some programming languages). So yeah, try to having conditional in your code, it will bring a bit more effort on your side but will be super worth in the long run for everybody. Performance matters, money-wise too. – kissu Mar 14 '22 at 10:17
  • 2
    @kissu This was not a very useful answer while you should not make assumptions – user1469734 Mar 14 '22 at 14:56

2 Answers2

7

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: /.*/
    }
],
Ihar Aliakseyenka
  • 9,587
  • 4
  • 28
  • 38
  • I guess that having an empty `content` may be equivalent to not having a `purge`: https://tailwindcss.com/docs/content-configuration – kissu Mar 14 '22 at 10:44
  • I tried empty content it ignores everything but basic utilities – Ihar Aliakseyenka Mar 14 '22 at 10:47
  • `it ignores` > no purge at all? What do you call basic utilities? – kissu Mar 14 '22 at 10:49
  • Yes no purge at all - compiled CSS contains `img, svg, video` etc - basically what will be generated by `@tailwind base;` – Ihar Aliakseyenka Mar 14 '22 at 10:52
  • I guess before JIT Tailwind compiled full CSS file and purged it in a production mode depends on your content (purge section). Now it has different approach - CSS generated on the fly if your content contains utility. So as there is no content - there is nothing to purge and only base styles generated – Ihar Aliakseyenka Mar 14 '22 at 10:58
  • FWIW, I think this regexp is not really correct, based on their documentation. the periods in that regexp only allow one character, probably you are meaning to use `.*` instead of just `.` – Jay Jun 27 '22 at 18:09
0

I found using safelist in the Tailwinds config with an expression to match all works to output a file which currently is just over 8mb and has 404,324 lines. I believe that is 100% of the classes available, I've spot tested a few colors, padding and animations, and they all seem to be there. That number 8mb seems to match what I've heard raw Tailwinds would be if output in total, so I'm reasonably sure I've got a full output.

I'm planning to build a PHP purging system for WordPress. So this full output file is needed to act as the input for that.

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

Below is the safelist in the context of the full tailwind.config.js file.

module.exports = {
  content: ["./src/**/*.{html,js}"],
  safelist: [
    {
      pattern: /.*/,
    }
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Perhaps worth noting that with this configuration you need to run the build as described in the Tailwind CSS docs. The resulting file takes an unusual amount of time to build, as much as 2-4 minutes depending on your machine.

The nice thing about this approach compared to CDN's is that you can run it again anytime there is an update, and if you don't really need 100% of the available classes you can make the regex more selective.