CSSComb is a coding style formatter for CSS. You can easily write your own configuration to make your style sheets beautiful and consistent.
The main feature is the sorting properties in specific order. It was inspired by the same-named @miripiruni's PHP-based tool. This is the new JavaScript version, based on powerful CSS parser Gonzales PE.
Global installation (use as a command-line tool):
npm install csscomb -gLocal installation (use as a command-line tool within current directory):
npm install csscombTo install as a project dependency (package will appear in your dependencies):
npm install csscomb --saveTo install as a dev dependency (package will appear in your devDependencies):
npm install csscomb --save-devTo run csscomb:
csscomb path[ path[...]]If you installed the package locally, in the project's directory run:
./node_modules/.bin/csscomb path[ path[...]]If you run csscomb -h, it will show some helpful information:
csscomb -h
Usage: csscomb [options] <file ...>
Options:
-h, --help output usage information
-V, --version output the version number
-v, --verbose verbose mode
-c, --config [path] configuration file path
-l, --lint in case some fixes needed returns an errorBesides being a great CLI, csscomb can be used in Node.js projects (inside
a plugin or as a dev tool):
// Require:
var Comb = require('csscomb');
// Configure:
var comb = new Comb();
comb.configure(config);
// Use:
comb.processPath('style.css');You must configure csscomb before using and config must be a valid JSON.
See configuration section for more information.
Comb a file or a directory.
Warning: This method rewrites the file.
// One file:
comb.processPath('main.scss');
// Whole directory:
comb.processPath('assets/styles');Comb all supported files in a directory.
Warning: This method rewrites the files.
comb.processDirectory('public/css');Comb one file.
If file's syntax is not supported, the file will be ignored.
Warning: This method rewrites the file.
comb.processFile('print.less');Comb a stylesheet.
If style's syntax is different from css, you should pass syntax parameter,
too.
filename is optional, it's used to print possible errors.
// Comb a css string:
var css = 'a {top: 0; left: 0}';
var combedCSS = comb.processString(css);
// Comb a less string:
var less = '@color: tomato; a {color: @color}';
var combedLESS = comb.processString(less, 'less');csscomb is configured using .csscomb.json file, located in the project root.
Example configuration:
{
"exclude": ["node_modules/**"],
"verbose": true,
"always-semicolon": true,
"block-indent": true,
"colon-space": true,
"color-case": "lower",
"color-shorthand": true,
"element-case": "lower",
"eof-newline": true,
"leading-zero": false,
"remove-empty-rulesets": true,
"rule-indent": true,
"stick-brace": true,
"strip-spaces": true,
"unitless-zero": true,
"vendor-prefix-align": true
}Available values: {String[]}
Array of Ant path patterns to exclude.
Example: { "exclude": ["node_modules/**"] } - exclude all files and directories under node_modules dir.
Available value: {Boolean} true
Config mode: { "verbose": true }
./bin/csscomb ./test
✓ test/integral.origin.css
test/integral.expect.css
2 files processed
1 file fixed
96 ms spentCLI mode:
./bin/csscomb ./test --verbose
./bin/csscomb ./test -vWhether to add a semicolon after the last value/mixin.
Available value: {Boolean} true
Example: { "always-semicolon": true }
/* before */
a { color: red }
/* after */
a { color: red; }Example: { "always-semicolon": true } (scss file):
// before
div {
color: tomato;
@include nani
}
// after
div {
color: tomato;
@include nani;
}Note that in *.scss and *.less files semicolons are not added after }
even if it's part of a value:
// before
div {
color: tomato;
font: {
family: fantasy;
size: 16px
}
}
// after
div {
color: tomato;
font: {
family: fantasy;
size: 16px;
}
}Note: better to use with rule-indent
Available values:
{Boolean}true(means 4 spaces){Number}of spaces{String}of whitespace characters (/[ \t]+/)
Example: { "block-indent": 2 }
/* before */
a { color: red }
@media all { a { color: green } }
/* after */
a { color: red
}
@media all {
a { color: green
}
}Available values:
{Boolean}true(meansafter) orfalse(no whitespace at all){String}:before,after,bothor any combination of whitespaces and/or a colon (,:,\t:\n\tetc.){Array}with two{String}values: for setting left and right whitespace around a colon
Example: { "colon-space": true }
/* before */
a { color:red }
/* after */
a { color: red }Example: { "colon-space": ":\n\t\t" }
/* before */
a {
color: red;
}
/* after */
a {
color:
red;
}Example: { "colon-space": "" }
/* before */
a { color: red }
/* after */
a { color:red }Example: { "colon-space": ["\t", "\t"] }
/* before */
a { color: red }
/* after */
a { color : red }Available values: {String} lower or upper
Example: { "color-case": "lower" }
/* before */
a { color: #FFF }
/* after */
a { color: #fff }Available values: {Boolean} true or false
Example: { "color-shorthand": true }
/* before */
b { color: #ffcc00 }
/* after */
b { color: #fc0 }Available values:
{Boolean}:truesets one space,falseremoves the spaces.{String}: any combination of whitespaces.{Array}with two{String}values: for setting left and right whitespace.
Example: { "combinator-space": true }
/* before */
a>b { color: red }
/* after */
a > b { color: red }Example: { "combinator-space": "" }
/* before */
a > b { color: red }
/* after */
a>b { color: red }Example: { "combinator-space": [" ", "\n"] }
/* before */
a>b { color: red }
/* after */
a >
b { color: red }Available values: {String} lower or upper
Example: { "element-case": "upper" }
/* before */
li > a { color: red }
/* after */
LI > A { color: red }Available values: {Boolean} true or false
Example: { "eof-newline": true }
a { color: red } → a { color: red }\n
Example: { "eof-newline": false }
a { color: red }\n → a { color: red }
Available values: {Boolean} true or false
Example: { "leading-zero": false }
/* before */
p { padding: 0.5em }
/* after */
p { padding: .5em }Available values: {Boolean} true
Example: { "remove-empty-rulesets": true } - remove rulesets that have no declarations or comments.
a { color: red; } p { /* hey */ } b { } → a { color: red; } p { /* hey */ }
Note: better to use with block-indent
Available values:
{Boolean}true(means 4 spaces){Number}of spaces{String}of whitespace characters (/[ \t]+/)
Example: { "rule-indent": 2 }
/* before */
a { color:red; margin:0 }
/* after */
a {
color:red;
margin:0 }Note: you can use an example of .csscomb.json to set your own sort order
Available values:
{Array}of rules{Array}of arrays of rules for groups separation
Example: { "sort-order": [ "margin", "padding" ] }
/* before */
p {
padding: 0;
margin: 0;
}
/* after */
p {
margin: 0;
padding: 0;
}Example: { "sort-order": [ [ "margin", "padding" ], [ "border", "background" ] ] }
/* before */
p {
background: none;
border: 0;
margin: 0;
padding: 0;
}
/* after */
p {
margin: 0;
padding: 0;
border: 0;
background: none;
}If you sort properties in *.scss or *.less files, you can use one of 3
keywords in your config:
$variablefor variable declarations (e.g.$varin Sass or@varin LESS);$includefor included mixins (e.g.@include ...and@extend ...in Sass or.mixin()in LESS);$importfor@importrules.
Example: { "sort-order": [ [ "$variable" ], [ "$include" ], [ "top", "padding" ] ] }
/* before */
p {
padding: 0;
@include mixin($color);
$color: tomato;
top: 0;
}
/* after */
p {
$color: tomato;
@include mixin($color);
top: 0;
padding: 0;
}Available values:
{Boolean}true(means 1 space){Number}of spaces{String}of whitespace characters (/[ \t\n]+/)
Example: { "stick-brace": "\n" }
/* before */
a { color:red }
/* after */
a
{ color:red }Available value: {Boolean} true
Example: { "strip-spaces": true }
a { color: red } \n \n \n → a { color: red }\n
a { color: red }\t → a { color: red }
Available value: {Boolean} true
Example: { "unitless-zero": true }
/* before */
img { border: 0px }
/* after */
img { border: 0 }Available value: {Boolean} true
Example: { "vendor-prefix-align": true }
/* before */
a
{
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
background: linear-gradient(to bottom, #fff 0, #eee 100%);
}
/* after */
a
{
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
background: linear-gradient(to bottom, #fff 0, #eee 100%);
}Run npm test for tests.
Anyone and everyone is welcome to contribute. Please take a moment to review the guidelines for contributing.
Thanks for assistance and contributions:
@miripiruni, @puzankov, @L0stSoul, @ignovak, @kizu, @anton-rudeshko, @mishaberezin
This software is released under the terms of the MIT license.

