stoffel.io

Statamic Tip: Using Tailwind Classes as Select Options

Not only does Statamic come with Tailwind CSS out of the box, the utility-first CSS framework is also gaining popularity rapidly on its own. So it's safe to assume that a lot of people building their first Statamic site will be using Tailwind classes when doing so.

And quite a few of them will probably run into the same issue at least once: classes suddenly not working because they were removed automatically.

The reason is Tailwind's compiler, which runs after each file change and deletes any class that doesn't appear to be used anywhere in the project. This helps to keep your stylesheet small and your website's load time low.

Giving the User Options in the Backend

It can be a bit of pain in some occasions though.

Here's a scenario we come across quite often: the user should be able to chose how an element is displayed on the site, given certain options. For example, we often let users choose the max-width of different containers or give them a couple options for the background-color of a section.

So in the first scenario we would like to include a select field that has narrow, normal and wide as labels and the corresponding Tailwind classes max-w-sm, max-w-md and max-w-lg as values.

/resources/fieldsets/example.yaml (excerpt)
handle: maxwidh field: options: max-w-sm: narrow max-w-md: normal max-w-lg: wide ...
An example where the user can pick one of three Tailwind classes for a setting

The problem: if we run npm run production while one of those values isn't used anywhere on the site, but then the users selects it in the backend afterwards, the corresponding class might not exist in your tailwind.css file, while the others do, leading to a broken layout and a lot of head scratching.

In the beginning we tried a few workarounds. One was adding all the classes to a comment in the corresponding template file to make sure they showed up in the code at least once. Another approach was using other values (e.g. narrow) for the select and then adding the Tailwind classes using if-clauses.

Both solutions added unnecessary bloat to our code and made it harder for us to add additional options, as we also had to update the template each time.

Preserving Tailwind Classes in Fieldsets

The better way of doing it is simple: tell Tailwind to also leave any classes used in your blueprints and fieldsets untouched. This can be achieved by adding a single line to your tailwind.config.js:

tailwind.config.js (excerpt)
module.exports = { content: [ './resources/**/*.antlers.html', './resources/**/*.blade.php', './resources/**/*.vue', './content/**/*.md', './resources/**/*.yaml', ], ... }
Adding .yaml files (line 7) to Tailwind's content array

Now whenever Tailwind purges unused classes it not only checks your views and content files, but also your blueprints and fieldsets. This way any Tailwind classes your users can pick in the backend will always be included in your stylesheet.

So now we can keep our view files clean and flexible:

// View
<section class="{{ background }}">
  <div class="mx-auto {{ maxwidth }}">
	{{ content }}
  </div>
</section>

// Output
<section class="bg-blue-400">
  <div class="mx-auto max-w-lg">
	This is the content.
  </div>
</section>
An example of a view including Tailwind classes selected by the user

There isn't really any downside to this approach that we have found. The small number of .yaml files doesn't really impact Tailwind's performance, and the chance of keeping unneeded classes in your stylesheet is also negligible.

More posts: