How to Minify CSS
Minifying CSS removes unnecessary characters (whitespace, comments, line breaks) to reduce file size and improve page load speed. This tutorial shows you how to minify CSS using online tools, command-line utilities, and build tool integrations.
Why Minify CSS?
| Benefit | Impact | |---------|--------| | Smaller file size | 30-50% reduction typical | | Faster page load | Less data to download | | Better Core Web Vitals | Improved LCP score | | Lower bandwidth costs | Important for high-traffic sites |
Example:
/ Before (234 bytes) /
.header {
background-color: #3B82F6;
padding: 20px;
margin: 0;
display: flex;
justify-content: center;
}/ After (78 bytes) /
.header{background-color:#3B82F6;padding:20px;margin:0;display:flex;justify-content:center}
Method 1: Online CSS Minifiers
Quick option for one-off files:
Popular Tools
- CSSNano - cssnano.co
- Clean-CSS - clean-css.com
- Minify Code - minifycode.com
How to Use
1. Paste your CSS into the input field
2. Click "Minify" or "Compress"
3. Copy the minified output
4. Save as .min.css
⚠️ Warning: Don't paste sensitive or proprietary CSS into online tools.
Method 2: Command Line with cssnano
For local processing:
# Install cssnano globally
npm install -g cssnano-cliMinify a single file
cssnano input.css output.min.cssOr use with pipe
cat input.css | cssnano > output.min.cssUsing PostCSS CLI
# Install
npm install -g postcss postcss-cli cssnanoCreate postcss.config.js
echo "module.exports = { plugins: [require('cssnano')] }" > postcss.config.jsMinify
postcss input.css -o output.min.cssMethod 3: Using clean-css CLI
# Install
npm install -g clean-css-cliBasic minification
cleancss input.css -o output.min.cssWith advanced options
cleancss --level 2 --source-map input.css -o output.min.cssclean-css Optimization Levels
| Level | Description | Size Reduction | |-------|-------------|----------------| | 0 | No optimization | ~10% | | 1 (default) | Safe optimizations | ~30% | | 2 | Advanced restructuring | ~40% |
Method 4: Build Tool Integration
Vite (Automatic)
Vite minifies CSS automatically in production builds:
// vite.config.js
export default {
build: {
minify: 'esbuild', // or 'terser'
cssMinify: 'esbuild'
}
}npm run build # CSS is automatically minifiedWebpack with css-minimizer-webpack-plugin
npm install -D css-minimizer-webpack-plugin// webpack.config.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');module.exports = {
optimization: {
minimizer: [
'...',
new CssMinimizerPlugin({
minimizerOptions: {
preset: ['default', { mergeLonghand: true }]
}
})
]
}
};
Rollup with rollup-plugin-postcss
npm install -D rollup-plugin-postcss cssnano// rollup.config.js
import postcss from 'rollup-plugin-postcss';
import cssnano from 'cssnano';export default {
plugins: [
postcss({
plugins: [
cssnano({
preset: 'default'
})
]
})
]
};
Method 5: Node.js Programmatic Minification
const CleanCSS = require('clean-css'););const minified = new CleanCSS({ level: 2, sourceMap: true, rebase: false }).minify(
.header { background-color: #3B82F6; padding: 20px; }.footer { margin-top: 20px; }
console.log(minified.styles); // .header{background-color:#3B82F6;padding:20px}.footer{margin-top:20px} console.log(minified.errors); // [] console.log(minified.warnings); // []
Batch Minify Multiple Files
const CleanCSS = require('clean-css');
const fs = require('fs');
const path = require('path');async function minifyCssFiles(inputDir, outputDir) {
const files = fs.readdirSync(inputDir).filter(f => f.endsWith('.css'));
for (const file of files) {
const inputPath = path.join(inputDir, file);
const outputName = file.replace('.css', '.min.css');
const outputPath = path.join(outputDir, outputName);
const css = fs.readFileSync(inputPath, 'utf-8');
const minified = new CleanCSS({ level: 2 }).minify(css);
if (minified.errors.length > 0) {
console.error(Error in ${file}:, minified.errors);
continue;
}
fs.writeFileSync(outputPath, minified.styles);
console.log(Minified ${file} → ${outputName});
}
}
// Usage
minifyCssFiles('./src/css', './dist/css');
CSS Minification in JavaScript (Browser)
For client-side minification:
function minifyCss(css) {
return css
// Remove comments
.replace(/\/\[\s\S]?\\//g, '')
// Remove whitespace around special characters
.replace(/\s([{}:;,>+~])\s/g, '$1')
// Remove trailing semicolons before closing brace
.replace(/;}/g, '}')
// Remove multiple spaces
.replace(/\s+/g, ' ')
// Remove leading/trailing whitespace
.trim();
}// Usage
const css =
.header {
background-color: #3B82F6;
padding: 20px;
}
;
const minified = minifyCss(css);
console.log(minified);
// .header{background-color:#3B82F6;padding:20px}
⚠️ Note: This is a simple implementation. For production, use established libraries.
Advanced Optimization Techniques
Remove Unused CSS
# Using PurgeCSS
npm install -g purgecsspurgecss --content /.html --css src/styles.css --output dist/
Combine Multiple Files
const fs = require('fs');
const CleanCSS = require('clean-css');const files = ['reset.css', 'layout.css', 'components.css', 'utilities.css'];
const combined = files.map(f => fs.readFileSync(f, 'utf-8')).join('\n');
const minified = new CleanCSS({ level: 2 }).minify(combined);
fs.writeFileSync('bundle.min.css', minified.styles);
Source Maps
const minified = new CleanCSS({
level: 2,
sourceMap: true,
sourceMapInlineSources: true
}).minify(css, { 'styles.css': css });// Save source map
fs.writeFileSync('styles.min.css.map', minified.sourceMap);
CSS Minification Comparison
| Tool | Speed | Compression | Build Integration | |------|-------|-------------|-------------------| | cssnano | Fast | Good | ✅ PostCSS | | clean-css | Fast | Excellent | ✅ CLI/Node | | esbuild | Very Fast | Good | ✅ Vite/Rollup | | terser | Medium | Excellent | ✅ Webpack |
Complete Build Script
// build-css.js
const fs = require('fs');
const path = require('path');
const CleanCSS = require('clean-css');
const gzipSize = require('gzip-size');const config = {
input: './src/css',
output: './dist/css',
level: 2
};
function formatBytes(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
async function build() {
if (!fs.existsSync(config.output)) {
fs.mkdirSync(config.output, { recursive: true });
}
const files = fs.readdirSync(config.input).filter(f => f.endsWith('.css'));
for (const file of files) {
const inputPath = path.join(config.input, file);
const outputName = file.replace('.css', '.min.css');
const outputPath = path.join(config.output, outputName);
const css = fs.readFileSync(inputPath, 'utf-8');
const originalSize = Buffer.byteLength(css, 'utf-8');
const minified = new CleanCSS({
level: config.level,
sourceMap: false
}).minify(css);
if (minified.errors.length > 0) {
console.error(❌ ${file}:, minified.errors);
continue;
}
const minifiedSize = Buffer.byteLength(minified.styles, 'utf-8');
const gzippedSize = await gzipSize(minified.styles);
const savings = ((1 - minifiedSize / originalSize) * 100).toFixed(1);
fs.writeFileSync(outputPath, minified.styles);
console.log(✅ ${file} → ${outputName});
console.log( Original: ${formatBytes(originalSize)});
console.log( Minified: ${formatBytes(minifiedSize)} (-${savings}%));
console.log( Gzipped: ${formatBytes(gzippedSize)});
}
}
build().catch(console.error);
Try It Online
Need to minify CSS quickly? Use our CSS Minifier for instant minification with size comparison.
Conclusion
For local development, use clean-css-cli or cssnano. For build tools, Vite handles it automatically, while Webpack and Rollup need plugins. Always verify minified CSS works correctly before deploying.
For related tools, see How to Test Regular Expressions for regex testing utilities.
---
Related Tools:
- CSS Minifier
- JSON Formatter
- HTML Minifier (coming soon)