Clean-CSS provides three distinct optimization levels, each building upon the previous level to provide increasingly aggressive minification strategies.
interface OptimizationLevelObject {
0?: object; // No optimizations, basic cleanup only
1?: Level1Options; // Property-level optimizations (default)
2?: Level2Options; // Rule-level and structural optimizations
}Level 0 performs only basic cleanup without any optimizations. This level is useful when you want to preserve the CSS exactly as written.
const minifier = new CleanCSS({ level: 0 });What Level 0 does:
Level 1 applies safe property-level optimizations that don't change the CSS structure or semantics.
interface Level1Options {
cleanupCharsets?: boolean; // Remove duplicate charset rules
normalizeUrls?: boolean; // Normalize URLs in url() functions
optimizeBackground?: boolean; // Optimize background property
optimizeBorderRadius?: boolean; // Optimize border-radius property
optimizeFilter?: boolean; // Optimize filter property
optimizeFontWeight?: boolean; // Optimize font-weight values
optimizeOutline?: boolean; // Optimize outline property
removeEmpty?: boolean; // Remove empty rules and blocks
removeNegativePaddings?: boolean; // Remove negative padding values
removeQuotes?: boolean; // Remove unnecessary quotes
removeWhitespace?: boolean; // Remove extra whitespace
replaceMultipleZeros?: boolean; // Replace multiple zeros with single zero
replaceTimeUnits?: boolean; // Replace time units (ms -> s)
replaceZeroUnits?: boolean; // Remove units from zero values
roundingPrecision?: number | object; // Rounding precision for numbers
selectorsSortingMethod?: string; // Selector sorting method
specialComments?: string; // Special comment handling
tidyAtRules?: boolean; // Tidy at-rules
tidyBlockScopes?: boolean; // Tidy block scopes
tidySelectors?: boolean; // Tidy selectors
variableValueOptimizers?: string[]; // CSS variable value optimizers
}const level1Defaults = {
cleanupCharsets: true,
normalizeUrls: true,
optimizeBackground: true,
optimizeBorderRadius: true,
optimizeFilter: true,
optimizeFontWeight: true,
optimizeOutline: true,
removeEmpty: true,
removeNegativePaddings: true,
removeQuotes: true,
removeWhitespace: true,
replaceMultipleZeros: true,
replaceTimeUnits: true,
replaceZeroUnits: true,
roundingPrecision: false, // Disabled by default
selectorsSortingMethod: 'standard',
specialComments: 'all',
tidyAtRules: true,
tidyBlockScopes: true,
tidySelectors: true,
variableValueOptimizers: []
};// Default level 1
const minifier = new CleanCSS({ level: 1 });
// Custom level 1 with specific options
const customLevel1 = new CleanCSS({
level: {
1: {
removeEmpty: false, // Keep empty rules
specialComments: 'none', // Remove all comments
roundingPrecision: 2 // Round to 2 decimal places
}
}
});
// Level 1 with variable value optimization
const variableOptimizer = new CleanCSS({
level: {
1: {
variableValueOptimizers: ['color', 'fraction', 'precision']
}
}
});Level 2 applies aggressive structural optimizations that can reorganize and merge CSS rules for maximum compression.
interface Level2Options {
mergeAdjacentRules?: boolean; // Merge adjacent rules with same selector
mergeIntoShorthands?: boolean; // Merge properties into shorthand
mergeMedia?: boolean; // Merge @media blocks
mergeNonAdjacentRules?: boolean; // Merge non-adjacent rules with same selector
mergeSemantically?: boolean; // Merge rules semantically (aggressive)
overrideProperties?: boolean; // Override properties with later ones
removeEmpty?: boolean; // Remove empty rules and blocks
reduceNonAdjacentRules?: boolean; // Reduce non-adjacent rules
removeDuplicateFontRules?: boolean; // Remove duplicate @font-face rules
removeDuplicateMediaBlocks?: boolean; // Remove duplicate @media blocks
removeDuplicateRules?: boolean; // Remove duplicate rules
removeUnusedAtRules?: boolean; // Remove unused at-rules
restructureRules?: boolean; // Restructure rules for better compression
skipProperties?: string[]; // Properties to skip optimization
}const level2Defaults = {
mergeAdjacentRules: true,
mergeIntoShorthands: true,
mergeMedia: true,
mergeNonAdjacentRules: true,
mergeSemantically: false, // Disabled for safety
overrideProperties: true,
removeEmpty: true,
reduceNonAdjacentRules: true,
removeDuplicateFontRules: true,
removeDuplicateMediaBlocks: true,
removeDuplicateRules: true,
removeUnusedAtRules: false, // Disabled for safety
restructureRules: false, // Disabled for safety
skipProperties: []
};// Default level 2
const level2Minifier = new CleanCSS({ level: 2 });
// Conservative level 2 (safer optimizations)
const safeLevel2 = new CleanCSS({
level: {
2: {
mergeSemantically: false,
restructureRules: false,
removeUnusedAtRules: false
}
}
});
// Aggressive level 2 (maximum compression)
const aggressiveLevel2 = new CleanCSS({
level: {
2: {
mergeSemantically: true,
restructureRules: true,
removeUnusedAtRules: true
}
}
});
// Level 2 with property skipping
const skipPropertiesLevel2 = new CleanCSS({
level: {
2: {
skipProperties: ['font-family', 'background-image']
}
}
});You can combine multiple optimization levels for fine-grained control:
const combinedLevels = new CleanCSS({
level: {
1: {
removeEmpty: true,
specialComments: 'none',
roundingPrecision: 2
},
2: {
mergeAdjacentRules: true,
mergeIntoShorthands: true,
mergeSemantically: false
}
}
});/**
* Rounding precision configuration for different unit types
* @typedef {object} RoundingPrecisionOptions
* @property {number|'off'} [ch] - Character unit precision
* @property {number|'off'} [cm] - Centimeter unit precision
* @property {number|'off'} [em] - Em unit precision
* @property {number|'off'} [ex] - Ex unit precision
* @property {number|'off'} [in] - Inch unit precision
* @property {number|'off'} [mm] - Millimeter unit precision
* @property {number|'off'} [pc] - Pica unit precision
* @property {number|'off'} [pt] - Point unit precision
* @property {number|'off'} [px] - Pixel unit precision
* @property {number|'off'} [q] - Quarter-millimeter unit precision
* @property {number|'off'} [rem] - Root em unit precision
* @property {number|'off'} [vh] - Viewport height unit precision
* @property {number|'off'} [vmax] - Viewport maximum unit precision
* @property {number|'off'} [vmin] - Viewport minimum unit precision
* @property {number|'off'} [vw] - Viewport width unit precision
* @property {number|'off'} ['%'] - Percentage unit precision
* @property {number|'off'} ['*'] - Default precision for all other units
*/Configure decimal precision for different unit types. Set to 'off' to disable rounding for specific units:
const precisionConfig = new CleanCSS({
level: {
1: {
roundingPrecision: {
'px': 0, // No decimals for pixels
'em': 3, // 3 decimals for em units
'rem': 3, // 3 decimals for rem units
'vh': 2, // 2 decimals for viewport units
'vw': 2, // 2 decimals for viewport units
'vmin': 2, // 2 decimals for viewport units
'vmax': 2, // 2 decimals for viewport units
'%': 2, // 2 decimals for percentages
'pt': 1, // 1 decimal for points
'pc': 2, // 2 decimals for picas
'in': 3, // 3 decimals for inches
'cm': 2, // 2 decimals for centimeters
'mm': 1, // 1 decimal for millimeters
'q': 0, // No decimals for quarter-millimeters
'ch': 2, // 2 decimals for character units
'ex': 2, // 2 decimals for ex units
'*': 'off' // Disable rounding for all other units
}
}
}
});Unit-Specific Examples:
// Absolute length units
const absoluteUnitsConfig = new CleanCSS({
level: { 1: { roundingPrecision: {
'px': 0, // 16.75px → 17px
'pt': 1, // 12.345pt → 12.3pt
'pc': 2, // 1.2345pc → 1.23pc
'in': 3, // 0.12345in → 0.123in
'cm': 2, // 2.5467cm → 2.55cm
'mm': 1, // 25.67mm → 25.7mm
'q': 0 // 102.5q → 103q
}}}
});
// Relative length units
const relativeUnitsConfig = new CleanCSS({
level: { 1: { roundingPrecision: {
'em': 3, // 1.23456em → 1.235em
'rem': 3, // 0.87654rem → 0.877rem
'ch': 2, // 4.567ch → 4.57ch
'ex': 2 // 2.345ex → 2.35ex
}}}
});
// Viewport units
const viewportUnitsConfig = new CleanCSS({
level: { 1: { roundingPrecision: {
'vh': 2, // 12.345vh → 12.35vh
'vw': 2, // 50.678vw → 50.68vw
'vmin': 1, // 10.567vmin → 10.6vmin
'vmax': 1 // 90.234vmax → 90.2vmax
}}}
});Control how selectors are sorted within merged rules:
const selectorSorting = new CleanCSS({
level: {
1: {
selectorsSortingMethod: 'alphabetical' // 'standard', 'alphabetical', 'none', false
}
}
});Control how special comments are handled:
const commentHandling = new CleanCSS({
level: {
1: {
specialComments: 'all' // 'all', 'none', '1', '0'
}
}
});'all': Keep all special comments'1': Keep first special comment only'0' or 'none': Remove all comments