PostCSS and classes in contentDir

I am trying to use Hugo Pipes for the first time, and had some issues in the bootstrap5 layout. I’m usure if I implemented this right, and if the issue I found with the implementation is workable or not.

Implementation

PostCSS.config.js:

module.exports = {
  plugins: {
    '@fullhuman/postcss-purgecss': {
      content: ['themes/soft-ui/layouts/**/*.html'],
      safelist: {
      greedy: ["/col.*/","offset",]
      },
    fontFace: false,
    variables: false
    },
    autoprefixer: {},
    cssnano: { preset: 'default' }
  }
};

baseof.html:

{{- $softUi := resources.Get "scss/soft-design-system-pro.scss" | resources.ToCSS (dict "enableSourceMap" false "outputStyle" "compressed") }}

{{ $styles := $softUi | postCSS (dict "config" "./assets/css/postcss.config.js") | minify  -}}

{{ with ($styles  ) }}
<style>
	{{.Content | safeCSS }}
</style>
{{ end }}

The problem

First, some of the bootstrap variables were not working, I fixed it by installing purgecss v3 instead, as per the documentation.

If you are using PostCSS 7, install @fullhuman/postcss-purgecss 3.0.0: npm i -D @fullhuman/postcss-purgecss@3.0.0 . From version 4.0, it is compatible with PostCSS >=8 only.

source

Second, some styles were missing. My belief is that they were not detected because content is pointing to layout files. Is it safe to point purgeCSS to the contentDir ?

  1. what is the content of soft-design-system-pro.scss? Maybe you are not loading all bootstrap styles.
  2. It could be that you are using beta2 styles with beta3 docs. There were changes between 1 and 2 or 2 and 3 where left and right was changed to start and end for ltr support.

I realised some days ago that a simple purgecss configuration (without any safelisting) is un-hiding hidden fields in forms. All other styles appear to be working.

By the way I am fighting with purgecss and bootstrap too and I have the feeling that it leaves too much in and removes the wrong classes. I have the theory that using @extend .bootstrap-classname for all my elements and not using a single bootstrap class in my layout files might solve the issue. Don’t ask why, there is no logical reason for this. Will report here once I am done going through my layouts :wink:

  1. That file loads all the styles + bootstrap’s full css. Using it alone shows the layout exactly how I want it.

  2. I also checked if it was running BS5, and had to change some of the content files to match float-start and float-end.

This seems to help load all the styles I need : content: ['themes/soft-ui/layouts/**/*.html','content/**/*.html', 'content/**/*.md'],

Yet, I am not sure how purgecss works in regard to markdown files that sometimes include html code.

If the configuration looks into public then the markdown is irrelevant and the purgecss scripts are looking into the resulting static files. Your config looks different than mine and looks into the layout files. That means they ignore whatever you do in markdown and shortcodes.

PS: maybe not the shortcodes.

Not sure if it is relevant for this problem, but I had to add some configuration for postcss-purgecss in Tailwind.
Some style where wrongly purged. And it took me some time and grey hairs to understand & solve this.

So, just in case it could help, this is my config.

// Source : https://github.com/bep/hugo-starter-tailwind-basic/blob/master/tailwind.config.js
// Modified for better whitelisting (bootstrap/venobox, ...)
// Adapted for this module v2

const theme = require('tailwindcss/defaultTheme');
const typography = require('@tailwindcss/typography');

//const colorBrand = 'var(--color-pretty)';

// Utils
const round = (num) => num.toFixed(7).replace(/(\.[0-9]+?)0+$/, '$1').replace(/\.0$/, '');
const rem = (px) => `${round(px / 16)}rem`;
const em = (px, base) => `${round(px / base)}em`;
const px = (px) => `${px}px`;

module.exports = {
	important: true, // See https://tailwindcss.com/docs/configuration#important
	purge: {
		enabled: process.env.HUGO_ENVIRONMENT === 'production',
      content: [
         './hugo_stats.json',
         './layouts/**/*.html',
      ],
      extractors: [
         {
         extractor: (content) => {
                  let els = JSON.parse(content).htmlElements;
                  return els.tags.concat(els.classes, els.ids);
               },
         extensions: ['json']
         },
      ],
		mode: 'all',
      options: {
         safelist: [
            // pour AOS plugin (Tested OK)
            /data-aos/,
            /data-aos^/,
            /^fade/,
            /^flip/,
            /^aos/,
            // pour bootstrap (Tested OK)
            /^btn-/,
            // pour MsgBox bootstrap (Tested OK)
            /show/,
            // pour venobox (Tested OK)
            /data-autoplay/,
            /data-vbtype/,
            /venoframe/,
            /vbvid/,
            /vbox-open/,
            /vbox-overlay/,
         ]
      }

	},
	plugins: [ typography ]
};

2 Likes