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.
Why we use it
Section titled “Why we use it”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.
How it is implemented
Section titled “How it is implemented”PurgeCSS runs as a PostCSS plugin (@fullhuman/postcss-purgecss) inside vite.config.js. It is already included in the starter kit.
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 withnpm run buildandnpm run local. Withnpm run virtualyou get the full CSS.content: the files PurgeCSS scans for class names. Every.js,.phpand.vuefile in the theme.skippedContentGlobs: folders that are never scanned.safelist.standard: keeps every selector that does not start withf--oru--. This is what limits purging to foundations and utilities.
Classes PurgeCSS can’t see
Section titled “Classes PurgeCSS can’t see”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.
Concatenated class names
Section titled “Concatenated class names”<!-- ❌ 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 stored in the database
Section titled “Classes stored in the database”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]$/, ],},Check before deploying
Section titled “Check before deploying”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...