Skip to content

PurgeCSS

PurgeCSS is a tool that removes unused CSS from the final stylesheet. It scans the project files for class names and drops every selector it can’t find.

In Terra projects it runs on production builds only and only purges foundations (f--) and utilities (u--). Components, global components and everything else are always kept.


Foundations and utilities are generated with loops over every value and every breakpoint. That produces thousands of classes, and a project only uses a fraction of them.

Until now, we commented out the foundation and utility SCSS we didn’t need to keep the CSS light. With PurgeCSS this is no longer necessary.


PurgeCSS runs as a PostCSS plugin (@fullhuman/postcss-purgecss) inside vite.config.js. It is already included in the starter kit.

vite.config.js
import purgeCSSPlugin from "@fullhuman/postcss-purgecss";
const isBuild = process.env.NODE_ENV === "production" || process.env.NODE_ENV === "local";
export default defineConfig({
css: {
postcss: isBuild
? {
plugins: [
purgeCSSPlugin({
content: [ '**/*.js', '**/*.php', '**/*.vue' ],
skippedContentGlobs: [ "node_modules/**", "dist/**", ".git/**" ],
safelist: {
standard: [/^(?!f--|u--)/],
},
}),
],
}
: undefined,
},
});

What each option does:

  • isBuild: PurgeCSS only runs with npm run build and npm run local. With npm run virtual you get the full CSS.
  • content: the files PurgeCSS scans for class names. Every .js, .php and .vue file in the theme.
  • skippedContentGlobs: folders that are never scanned.
  • safelist.standard: keeps every selector that does not start with f-- or u--. This is what limits purging to foundations and utilities.

PurgeCSS reads our files as plain text. If a class name doesn’t appear complete in a .php, .js or .vue file, it gets removed.

<!-- ❌ u--text-left and u--text-center are purged -->
<p class="u--text-<?= $align ?>">
<!-- ✅ both class names are written in full -->
<?php $align_class = $align === 'center' ? 'u--text-center' : 'u--text-left'; ?>
<p class="<?= $align_class ?>">

The same applies to JavaScript: classList.add('u--font-bold') is safe, classList.add('u--font-' + weight) is not.

Classes saved in content (WYSIWYG, Contact Form 7 markup, ACF values) don’t exist in our files. Add them to safelist.standard:

safelist: {
standard: [
/^(?!f--|u--)/,
// Stored in Contact Form 7 markup (DB)
/^u--border-(white-)?[trbl]$/,
],
},

Always run npm run build (or npm run local) and review the site before deploying.

Knowledge Check

Test your understanding of this section

Loading questions...