Purgecss removing rules that are only in media queries

Hi, has anyone else experienced this issue? I can’t find anything about it online, wonder if anyone could shed some light?

I’m using purgecss but its being too greedy for rules that are only inside a media query.

Example:

The below rule would be completely purged:

@include media-breakpoint-down(sm) {
    .rule {
      background: red;
    }
}

But if I do this, both rules remain:

.rule {
      background: blue;
}

@include media-breakpoint-down(sm) {
    .rule {
      background: red;
    }
}

It’s like it only recognises it if its first declared outside of a media query.

Thanks in advance.

How do you have PurgeCSS configured?

Hi @alwaysblank

This is my webpack.config.optimise file.

'use strict'; // eslint-disable-line

const { default: ImageminPlugin } = require('imagemin-webpack-plugin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const TerserPlugin = require('terser-webpack-plugin');
const whitelister = require('purgecss-whitelister');
const glob = require('glob-all');
const PurgecssPlugin = require('purgecss-webpack-plugin');

const config = require('./config');

let purge_css_exclude_css = ['html', 'body', /^hidden/, /^open/, /^visible/, /^active/];
let purge_css_exclude_files = whitelister([
  'acf-blocks/**/assets/styles/styles.scss',
  'assets/styles/common/*.scss',
  'assets/styles/blocks/*.scss',
  'assets/styles/components/*.scss',
  'assets/styles/single-product/*.scss',
  'assets/styles/*.scss',
  'assets/styles/*-*.scss',
]);

module.exports = {
  plugins: [
    new ImageminPlugin({
      optipng: { optimizationLevel: 2 },
      gifsicle: { optimizationLevel: 3 },
      pngquant: { quality: '65-90', speed: 4 },
      svgo: {
        plugins: [
          { removeUnknownsAndDefaults: false },
          { cleanupIDs: false },
          { removeViewBox: false },
        ],
      },
      plugins: [imageminMozjpeg({ quality: 75 })],
      disable: (config.enabled.watcher),
    }),
    new PurgecssPlugin({
      paths: glob.sync([
        'acf-blocks/**/*.php',
        'templates/**/*.php',
        'woocommerce/**/*.php',
        'page.php',
        'base.php',
        'single.php',
        '404.php',
        'index.php',
        'search.php',
      ]),
      safelist: purge_css_exclude_css.concat(purge_css_exclude_files),
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
  },
};

My gut feeling is that somehow your webpack config is running PurgeCSS before webpack has processed your SCSS into CSS—@include media-breakpoint-down(sm) { ... } is invalid CSS, so I’m guessing PurgeCSS would just skip whatever is inside it. IIRC when I was adding PurgeCSS support to things, I usually added it via PostCSS which worked pretty well (and by which point you know you have valid CSS).

Hi @alwaysblank

Thanks for the suggestion.

To test that I tried replacing the media-break-down(sm) include with a normal media query but the same thing happened, so I don’t think that is the issue unfortunately.

Joel