SassなどのCSSプリプロセッサやAutoprefixerのようなポストプロセッサを利用すると、プロセッサ規定のインデントや改行方法でCSSが整形されます。これについては@myakuraさんがAutoprefixer ― CSSのベンダー接頭辞をいろいろする - fragmentaryの最後で懸念事項として上げられていましたし、僕も2011年の年末にSassで出力するCSSファイルを自社のCSS記述ルールに合わせるヒントで、Sassをカスタマイズして解決する方法を紹介したりもしました。
Autoprefixerのdependenceであるpostcss(Framework for CSS postproccessors)を見ると、Whitespacesという項があり、インデントやスペースを調整できることが解説されています。これを利用すれば、CSS Beautifyのようなことがオフラインで実現でき、課題が解決できるのではと思い実験してみました。
※gruntやgulpのプラグインを見ましたが、完全にマッチするものは見つかりませんでした。
サンプルコード
Sassでコンパイルし、Autoprefixerを通したCSS
@charset "UTF-8";
.lyt-column .unit {
float: left;
margin-right: 20px;
}
.lyt-column .unit.last-unit {
margin-right: 0;
}
@media print{
nav{
display: none;
}
}
pretty.js - CSSを整形するスクリプト
中程のdecl.before
やrule.before
等の値を変更して、整形方法を指定します。どの部分が変わるかは、コメントで記載しておきました。
var fs = require("fs")
var postcss = require("postcss");
var prettifier = postcss(function (css) {
css.eachDecl(function (decl) {
decl.before = "\n"; // before property name
decl.between = ":"; // between property name and value
});
css.eachRule(function (rule) {
rule.before = "\n\n"; // before selector
rule.between = ""; // before {
rule.after = "\n"; // before }
});
css.eachAtRule(function (atRule) {
atRule.before = "\n\n"; // before @
atRule.between = ""; // before {
atRule.after = "\n\n"; // before }
});
});
var css = fs.readFileSync("before.css");
var prettycss = prettifier.process(css).css.trim();
fs.writeFile("after.css", prettycss, function () {
console.log("Process Done!");
});
実行方法
準備
Node.jsとpostcssを利用します。npm install postcss
でpostcssをプロジェクトディレクトリにインストールします。npm install -g postcss
でインストールして、プロジェクトディレクトリでnpm link postcss
をしても良いかもしれません。
実行
node pretty.js
を実行します。Process Done!と表示されると、after.cssが出力されています。
出力サンプル
console.log
で出力してみました。
サンプル1
Sassのexpandedからスペースを取り除いたり、}の後ろに1行空行を入れたものです。
サンプル2
プロパティの前のインデントを4スペースに、プロパティの後はセミコロン+スペース1つとしたものです。
css.eachDecl(function (decl) {
decl.before = "\n "; // before property name
decl.between = ": "; // between property name and value
});
まとめ
想定通りCSSの整形が行われることが分かりました。需要があるようであれば、gruntやgulpのプラグインにしても良いのかなと考えています。Source Mapsへの対応も必要ですね。
2014.02.17追記
grunt-cssprettyをリリースしました。詳しくは、Grunt.jsでCSSの整形を行うgrunt-cssprettyを公開をご覧下さい。