Tailwindcss + Tailwindcss-forms plugin purge issue, writeStats does not capture attribute selector

Hey, I have encountered a problem purging TailwindCSS while using the tailwindcss-forms plugin. The current purge setup deletes all base styles to reset the input elements.

My purge setup uses the hugo_stats.json file to look for used classes on build time. Unfortunately, the writeStats option within Hugo parses the generated HTML for tags, classes and id’s only. But not for HTML input types or other element attributes. E.g. if you have an input <input type="text"> , it will list the tag input but not the attribute type="text".

The @tailwindcss/forms package on the other side uses the css attribute selector [type='text'] to reset the base styles of the input elements. As the attribute [type='text'] is not listed in the hugo_stats.json file, these base styles will get purged.

The only solution I can think of is to add parsing for HTML element attributes to the Hugo HTML parser and add these to the hugo_stats.json file.

For the time being, a work around by adding the /* purgecss start ignore */ clause to the @import "tailwindcss/base" and @import "tailwindcss/components" statement fixes it.

Any suggestions on how to approach this?

See my repo dirkolbrich/hugo-theme-tailwindcss-starter for a reproducible example.

Whoop, just seen the issue Collect attributes in hugo_stats.json · Issue #7560 · gohugoio/hugo · GitHub. I will dig myself into the parser code.

Any directions which packages/files are the best place for this?


I was wondering if you’ve made any progress on this issue or managed to find a workaround? I’m currently stuck on the same problem… I’ve tried to add a manual “content” with the classes to the postcss.config and tried whitelisting both without success…

Hey. No, unfortunately not real progress from my side on this issue. I startet to tweak the underlying code for the hugoStats file, but abandoned my efforts due to coding practices.
I don’t know how far the Hugo projects is currently on this issue, as I haven’t done anything with Hugo lately.

There is a workaround. Just exempt the tailwinds/base and tailwinds/components classes from purging by adding a /* purges start ignore */ comment. The Tailwindcss plug-ins will then be ignored during the purging stage. This will add some weight to the resulting css file, but not that much (around 16kb in the case of the `tailwinds/typography plug-in).

/* purgecss start ignore */
/* Tailwind base - put variables under: tailwind.config.js */
@import "node_modules/tailwindcss/base";
/* Tailwind component classes registered by plugins*/
@import "node_modules/tailwindcss/components";
/* purgecss end ignore */
/* Site Specific */
@import "assets/css/site";
/* Tailwind's utility classes - generated based on config file */
@import "node_modules/tailwindcss/utilities";

Note: If you want to contribute to Hugo by adding HTML input types or other element attributes to hugoStats, the publisher/htmlElementsCollector.go file is the right place to start.

For some strange reasons, this didn’t work as well… The issue I’m running into is that the reset classes of tailwind forms were still purged. I’ve now worked around this by copying the reset-code into a dedicated css file and referencing this file instead. This has the additional advantage, that the resulting css file is still rather small.

Unfortunately I’ve never worked with Go, so I’m not sure if I’ll be able to help with the underlying issue…

I haven’t tried it yet, but using classes instead of element selectors might be a good strategy.

It do work! :smile:

It’s on my list of things to fix. I assume you can add these selectors to the safelist in purge config (those can be regexps, so you should able to match those).

purge: {
		enabled: process.env.HUGO_ENVIRONMENT === 'production',
		mode: 'all',
		content: [ './hugo_stats.json' ],
		safelist: [ /some-regexp-matching-form-elements/ ],
		options: {
			defaultExtractor: (content) => {
				let els = JSON.parse(content).htmlElements;
				els = els.tags.concat(els.classes, els.ids);
				return els;

This seem to work:

safelist: [ /type/ ]

A little coarse grained, but it doesn’t seem to make the CSS too much bigger. Also see Form styling selectors are removed by purgeCSS despite adding `[type='text']` into the purgeCSS safelist option. · Issue #419 · tailwindlabs/tailwindui-issues · GitHub