How to Minify CSS for Production
CSS minification removes whitespace, comments, and redundant syntax to reduce file size without changing any visual behaviour. A typical stylesheet might shrink from 80 KB to 55 KB — a 30% reduction that costs nothing but a build step.
What minification does
A minifier converts this:
/* Button styles */
.button {
display: inline-flex;
align-items: center;
padding: 8px 16px;
background-color: #3b82f6;
color: #ffffff;
border-radius: 4px;
font-size: 14px;
}
.button:hover {
background-color: #2563eb;
}
Into this:
.button{display:inline-flex;align-items:center;padding:8px 16px;background-color:#3b82f6;color:#fff;border-radius:4px;font-size:14px}.button:hover{background-color:#2563eb}
Specifically: removes whitespace, newlines, and comments; shortens #ffffff to #fff; removes the last semicolon before }; removes spaces around colons and brackets.
More advanced minifiers also merge duplicate selectors, remove vendor prefixes no longer needed, and optimize 0px to 0.
Method 1: PostCSS + cssnano (the standard build tool approach)
If you're using a build tool (webpack, Vite, Parcel, Rollup), cssnano is the most widely used CSS minifier:
npm install --save-dev postcss cssnano
postcss.config.js:
module.exports = {
plugins: [
require('cssnano')({ preset: 'default' }),
],
};
In Vite this happens automatically in production builds via the built-in CSS pipeline. In webpack:
// webpack.config.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new CssMinimizerPlugin()],
},
};
Method 2: LightningCSS (fastest)
LightningCSS is a Rust-based CSS parser, transformer, and minifier. It's significantly faster than cssnano and handles modern CSS features:
npm install --save-dev lightningcss-cli
# Minify a single file
npx lightningcss --minify --bundle styles.css -o styles.min.css
# With browser targets
npx lightningcss --minify --targets '>= 0.25%' styles.css -o styles.min.css
Vite 4+ uses LightningCSS by default. If you're starting a new project, it's the recommended choice.
Method 3: clean-css (Node.js API)
npm install clean-css-cli
# CLI
npx cleancss -o styles.min.css styles.css
# With source map
npx cleancss -o styles.min.css --source-map styles.css
As a Node.js API:
const CleanCSS = require('clean-css');
const fs = require('fs');
const input = fs.readFileSync('styles.css', 'utf8');
const output = new CleanCSS({ level: 2 }).minify(input);
fs.writeFileSync('styles.min.css', output.styles);
console.log(`Reduced from ${input.length} to ${output.styles.length} bytes`);
Level 1 does safe transformations (whitespace, comments). Level 2 merges rules and does more aggressive optimizations — test your output carefully at level 2.
Method 4: Python (css-html-js-minify)
pip install css-html-js-minify
from css_html_js_minify import css_minify
with open('styles.css', 'r') as f:
css = f.read()
minified = css_minify(css)
with open('styles.min.css', 'w') as f:
f.write(minified)
Or from the command line:
css-html-js-minify styles.css
# outputs styles.min.css
Gzip / Brotli compression on top
Minification and compression work on different things:
- Minification removes unnecessary characters — the output file is smaller.
- Gzip/Brotli exploits repetition in the file to compress it further.
Both together give the best results. Minification actually helps compression: removing variable names and whitespace increases the density of meaningful tokens, giving the compressor more repetition to work with.
On nginx:
gzip on;
gzip_types text/css;
gzip_min_length 256;
Typical final sizes for a 100 KB stylesheet:
| Step | Size |
|---|---|
| Original | 100 KB |
| After minification | ~65 KB |
| After gzip | ~15 KB |
| After brotli | ~12 KB |
Source maps
Always generate source maps in development so DevTools shows the original CSS lines when debugging:
npx lightningcss --minify --source-map styles.css -o styles.min.css
In production, source maps are optional — they can be served at a separate URL so end-users don't load them, but your team can still debug.
Key takeaways
- cssnano (PostCSS) and LightningCSS are the standard options for build-tool pipelines.
- LightningCSS is faster and handles modern CSS — prefer it for new projects.
- Level 2 minification (merging rules) is more aggressive; test the output before deploying.
- Minification + gzip typically reduces a stylesheet to 10–15% of its original size.
- Always generate source maps so you can debug in DevTools without the minified output.