clean-css is a fast and efficient CSS optimizer for [Node.js](http://nodejs.org/) platform and [any modern browser](https://jakubpawlowicz.github.io/clean-css).
* API and CLI interfaces are split, so API stays in this repository while CLI moves to [clean-css-cli](https://github.com/jakubpawlowicz/clean-css-cli);
*`root`, `relativeTo`, and `target` options are replaced by a single `rebaseTo` option - this means that rebasing URLs and import inlining is much simpler but may not be (YMMV) as powerful as in 3.x;
*`debug` option is gone as stats are always provided in output object under `stats` property;
*`roundingPrecision` is disabled by default;
*`roundingPrecision` applies to **all** units now, not only `px` as in 3.x;
*`processImport` and `processImportFrom` are merged into `inline` option which defaults to `local`. Remote `@import` rules are **NOT** inlined by default anymore;
* splits `inliner: { request: ..., timeout: ... }` option into `inlineRequest` and `inlineTimeout` options;
* remote resources without a protocol, e.g. `//fonts.googleapis.com/css?family=Domine:700`, are not inlined anymore;
* changes default Internet Explorer compatibility from 9+ to 10+, to revert the old default use `{ compatibility: 'ie9' }` flag;
* renames `keepSpecialComments` to `specialComments`;
* moves `roundingPrecision` and `specialComments` to level 1 optimizations options, see examples;
* moves `mediaMerging`, `restructuring`, `semanticMerging`, and `shorthandCompacting` to level 2 optimizations options, see examples below;
* renames `shorthandCompacting` option to `mergeIntoShorthands`;
* level 1 optimizations are the new default, up to 3.x it was level 2;
*`keepBreaks` option is replaced with `{ format: 'keep-breaks' }` to ease transition;
*`sourceMap` option has to be a boolean from now on - to specify an input source map pass it a 2nd argument to `minify` method or via a hash instead;
*`aggressiveMerging` option is removed as aggressive merging is replaced by smarter override merging.
## What's new in version 4.1
clean-css 4.1 introduces the following changes / features:
*`inline: false` as an alias to `inline: ['none']`;
*`multiplePseudoMerging` compatibility flag controlling merging of rules with multiple pseudo classes / elements;
*`removeEmpty` flag in level 1 optimizations controlling removal of rules and nested blocks;
*`removeEmpty` flag in level 2 optimizations controlling removal of rules and nested blocks;
*`compatibility: { selectors: { mergeLimit: <number> } }` flag in compatibility settings controlling maximum number of selectors in a single rule;
*`minify` method improved signature accepting a list of hashes for a predictable traversal;
*`selectorsSortingMethod` level 1 optimization allows `false` or `'none'` for disabling selector sorting;
*`fetch` option controlling a function for handling remote requests;
* new `font` shorthand and `font-*` longhand optimizers;
* removal of `optimizeFont` flag in level 1 optimizations due to new `font` shorthand optimizer;
*`skipProperties` flag in level 2 optimizations controlling which properties won't be optimized;
* new `animation` shorthand and `animation-*` longhand optimizers;
*`removeUnusedAtRules` level 2 optimization controlling removal of unused `@counter-style`, `@font-face`, `@keyframes`, and `@namespace` at rules;
* the [web interface](https://jakubpawlowicz.github.io/clean-css) gets an improved settings panel with "reset to defaults", instant option changes, and settings being persisted across sessions.
## What's new in version 4.2
clean-css 4.2 introduces the following changes / features:
* Adds `process` method for compatibility with optimize-css-assets-webpack-plugin;
* new `transition` property optimizer;
* preserves any CSS content between `/* clean-css ignore:start */` and `/* clean-css ignore:end */` comments;
* allows filtering based on selector in `transform` callback, see [example](#how-to-apply-arbitrary-transformations-to-css-properties);
* adds configurable line breaks via `format: { breakWith: 'lf' }` option.
## Constructor options
clean-css constructor accepts a hash as a parameter with the following options available:
*`compatibility` - controls compatibility mode used; defaults to `ie10+`; see [compatibility modes](#compatibility-modes) for examples;
*`fetch` - controls a function for handling remote requests; see [fetch option](#fetch-option) for examples (since 4.1.0);
*`format` - controls output CSS formatting; defaults to `false`; see [formatting options](#formatting-options) for examples;
*`inline` - controls `@import` inlining rules; defaults to `'local'`; see [inlining options](#inlining-options) for examples;
*`inlineRequest` - controls extra options for inlining remote `@import` rules, can be any of [HTTP(S) request options](https://nodejs.org/api/http.html#http_http_request_options_callback);
*`inlineTimeout` - controls number of milliseconds after which inlining a remote `@import` fails; defaults to 5000;
*`level` - controls optimization level used; defaults to `1`; see [optimization levels](#optimization-levels) for examples;
*`rebase` - controls URL rebasing; defaults to `true`;
*`rebaseTo` - controls a directory to which all URLs are rebased, most likely the directory under which the output file will live; defaults to the current directory;
*`returnPromise` - controls whether `minify` method returns a Promise object or not; defaults to `false`; see [promise interface](#promise-interface) for examples;
*`sourceMap` - controls whether an output source map is built; defaults to `false`;
*`sourceMapInlineSources` - controls embedding sources inside a source map's `sourcesContent` field; defaults to false.
## Compatibility modes
There is a certain number of compatibility mode shortcuts, namely:
*`new CleanCSS({ compatibility: '*' })` (default) - Internet Explorer 10+ compatibility mode
*`new CleanCSS({ compatibility: 'ie9' })` - Internet Explorer 9+ compatibility mode
*`new CleanCSS({ compatibility: 'ie8' })` - Internet Explorer 8+ compatibility mode
*`new CleanCSS({ compatibility: 'ie7' })` - Internet Explorer 7+ compatibility mode
Each of these modes is an alias to a [fine grained configuration](https://github.com/jakubpawlowicz/clean-css/blob/master/lib/options/compatibility.js), with the following options available:
```js
new CleanCSS({
compatibility: {
colors: {
opacity: true // controls `rgba()` / `hsla()` color support
},
properties: {
backgroundClipMerging: true, // controls background-clip merging into shorthand
backgroundOriginMerging: true, // controls background-origin merging into shorthand
backgroundSizeMerging: true, // controls background-size merging into shorthand
colors: true, // controls color optimizations
ieBangHack: false, // controls keeping IE bang hack
This option provides a convenient way of overriding the default fetching logic if it doesn't support a particular feature, say CONNECT proxies.
Unless given, the default [loadRemoteResource](https://github.com/jakubpawlowicz/clean-css/blob/master/lib/reader/load-remote-resource.js) logic is used.
afterAtRule: false, // controls if a line break comes after an at-rule; e.g. `@charset`; defaults to `false`
afterBlockBegins: false, // controls if a line break comes after a block begins; e.g. `@media`; defaults to `false`
afterBlockEnds: false, // controls if a line break comes after a block ends, defaults to `false`
afterComment: false, // controls if a line break comes after a comment; defaults to `false`
afterProperty: false, // controls if a line break comes after a property; defaults to `false`
afterRuleBegins: false, // controls if a line break comes after a rule begins; defaults to `false`
afterRuleEnds: false, // controls if a line break comes after a rule ends; defaults to `false`
beforeBlockEnds: false, // controls if a line break comes before a block ends; defaults to `false`
betweenSelectors: false // controls if a line break comes between selectors; defaults to `false`
},
breakWith: '\n', // controls the new line character, can be `'\r\n'` or `'\n'` (aliased as `'windows'` and `'unix'` or `'crlf'` and `'lf'`); defaults to system one, so former on Windows and latter on Unix
indentBy: 0, // controls number of characters to indent with; defaults to `0`
indentWith: 'space', // controls a character to indent with, can be `'space'` or `'tab'`; defaults to `'space'`
spaces: { // controls where to insert spaces
aroundSelectorRelation: false, // controls if spaces come around selector relations; e.g. `div > a`; defaults to `false`
beforeBlockBegins: false, // controls if a space comes before a block begins; e.g. `.block {`; defaults to `false`
beforeValue: false // controls if a space comes before a value; e.g. `width: 1rem`; defaults to `false`
},
wrapAt: false // controls maximum line length; defaults to `false`
}
})
```
## Inlining options
`inline` option whitelists which `@import` rules will be processed, e.g.
Please note that level 1 optimization options are generally safe while level 2 optimizations should be safe for most users.
### Level 0 optimizations
Level 0 optimizations simply means "no optimizations". Use it when you'd like to inline imports and / or rebase URLs but skip everything else.
### Level 1 optimizations
Level 1 optimizations (default) operate on single properties only, e.g. can remove units when not required, turn rgb colors to a shorter hex representation, remove comments, etc
Here is a full list of available options:
```js
new CleanCSS({
level: {
1: {
cleanupCharsets: true, // controls `@charset` moving to the front of a stylesheet; defaults to `true`
normalizeUrls: true, // controls URL normalization; defaults to `true`
optimizeBackground: true, // controls `background` property optimizations; defaults to `true`
optimizeBorderRadius: true, // controls `border-radius` property optimizations; defaults to `true`
optimizeFilter: true, // controls `filter` property optimizations; defaults to `true`
optimizeFont: true, // controls `font` property optimizations; defaults to `true`
optimizeFontWeight: true, // controls `font-weight` property optimizations; defaults to `true`
optimizeOutline: true, // controls `outline` property optimizations; defaults to `true`
removeEmpty: true, // controls removing empty rules and nested blocks; defaults to `true`
removeNegativePaddings: true, // controls removing negative paddings; defaults to `true`
removeQuotes: true, // controls removing quotes when unnecessary; defaults to `true`
removeWhitespace: true, // controls removing unused whitespace; defaults to `true`
replaceMultipleZeros: true, // contols removing redundant zeros; defaults to `true`
replaceTimeUnits: true, // controls replacing time units with shorter values; defaults to `true`
replaceZeroUnits: true, // controls replacing zero values with units; defaults to `true`
roundingPrecision: false, // rounds pixel values to `N` decimal places; `false` disables rounding; defaults to `false`
selectorsSortingMethod: 'standard', // denotes selector sorting method; can be `'natural'` or `'standard'`, `'none'`, or false (the last two since 4.1.0); defaults to `'standard'`
specialComments: 'all', // denotes a number of /*! ... */ comments preserved; defaults to `all`
tidySelectors: true // turns on optimizing selectors
}
}
});
```
### Level 2 optimizations
Level 2 optimizations operate at rules or multiple properties level, e.g. can remove duplicate rules, remove properties redefined further down a stylesheet, or restructure rules by moving them around.
Please note that if level 2 optimizations are turned on then, unless explicitely disabled, level 1 optimizations are applied as well.
Clean-css has an associated command line utility that can be installed separately using `npm install clean-css-cli`. For more detailed information, please visit https://github.com/jakubpawlowicz/clean-css-cli.
# FAQ
## How to optimize multiple files?
It can be done either by passing an array of paths, or, when sources are already available, a hash or an array of hashes:
```js
new CleanCSS().minify(['path/to/file/one', 'path/to/file/two']);
Passing an array of hashes allows you to explicitly specify the order in which the input files are concatenated. Whereas when you use a single hash the order is determined by the [traversal order of object properties](http://2ality.com/2015/10/property-traversal-order-es6.html) - available since 4.1.0.
In order to inline remote `@import` statements you need to provide a callback to minify method as fetching remote assets is an asynchronous operation, e.g.:
All level 2 optimizations are dispatched [here](https://github.com/jakubpawlowicz/clean-css/blob/master/lib/optimizer/level-2/optimize.js#L67), and this is what they do:
*`recursivelyOptimizeBlocks` - does all the following operations on a nested block, like `@media` or `@keyframe`;
*`recursivelyOptimizeProperties` - optimizes properties in rulesets and flat at-rules, like @font-face, by splitting them into components (e.g. `margin` into `margin-(bottom|left|right|top)`), optimizing, and restoring them back. You may want to use `mergeIntoShorthands` option to control whether you want to turn multiple components into shorthands;
*`removeDuplicates` - gets rid of duplicate rulesets with exactly the same set of properties, e.g. when including a Sass / Less partial twice for no good reason;
*`mergeAdjacent` - merges adjacent rulesets with the same selector or rules;
*`reduceNonAdjacent` - identifies which properties are overridden in same-selector non-adjacent rulesets, and removes them;
*`mergeNonAdjacentBySelector` - identifies same-selector non-adjacent rulesets which can be moved (!) to be merged, requires all intermediate rulesets to not redefine the moved properties, or if redefined to have the same value;
*`mergeNonAdjacentByBody` - same as the one above but for same-selector non-adjacent rulesets;
*`restructure` - tries to reorganize different-selector different-rules rulesets so they take less space, e.g. `.one{padding:0}.two{margin:0}.one{margin-bottom:3px}` into `.two{margin:0}.one{padding:0;margin-bottom:3px}`;
* [@abarre](https://github.com/abarre) (Anthony Barre) for improvements to `@import` processing;
* [@alexlamsl](https://github.com/alexlamsl) (Alex Lam S.L.) for testing early clean-css 4 versions, reporting bugs, and suggesting numerous improvements.
* [@altschuler](https://github.com/altschuler) (Simon Altschuler) for fixing `@import` processing inside comments;
* [@ben-eb](https://github.com/ben-eb) (Ben Briggs) for sharing ideas about CSS optimizations;
* [@davisjam](https://github.com/davisjam) (Jamie Davis) for disclosing ReDOS vulnerabilities;
* [@facelessuser](https://github.com/facelessuser) (Isaac) for pointing out a flaw in clean-css' stateless mode;
* [@grandrath](https://github.com/grandrath) (Martin Grandrath) for improving `minify` method source traversal in ES6;
* [@jmalonzo](https://github.com/jmalonzo) (Jan Michael Alonzo) for a patch removing node.js' old `sys` package;
* [@lukeapage](https://github.com/lukeapage) (Luke Page) for suggestions and testing the source maps feature;
Plus everyone else involved in [#125](https://github.com/jakubpawlowicz/clean-css/issues/125) for pushing it forward;
* [@madwizard-thomas](https://github.com/madwizard-thomas) for sharing ideas about `@import` inlining and URL rebasing.
* [@ngyikp](https://github.com/ngyikp) (Ng Yik Phang) for testing early clean-css 4 versions, reporting bugs, and suggesting numerous improvements.
* [@wagenet](https://github.com/wagenet) (Peter Wagenet) for suggesting improvements to `@import` inlining behavior;
* [@venemo](https://github.com/venemo) (Timur Kristóf) for an outstanding contribution of advanced property optimizer for 2.2 release;
* [@vvo](https://github.com/vvo) (Vincent Voyer) for a patch with better empty element regex and for inspiring us to do many performance improvements in 0.4 release;
* [@xhmikosr](https://github.com/xhmikosr) for suggesting new features, like option to remove special comments and strip out URLs quotation, and pointing out numerous improvements like JSHint, media queries, etc.
# License
clean-css is released under the [MIT License](https://github.com/jakubpawlowicz/clean-css/blob/master/LICENSE).