PostCSSとは何か

PostCSSというnode.js製のツールがある。 PostCSSのGitHubでのStar数は4000を超え、海外のブログではPostCSSについての記事をよく目にするようになった。しかしまだ日本では盛り上がりを感じていないので、日本語のPostCSSの記事を書くことにした。

PostCSS

PostCSSとは、JavaScriptで書いたプラグインCSSを変換するためのツールだ。 PostCSS自体は、CSSパーサーとそのASTを操作するためのAPIのみを提供していて、ユーザーはPostCSSのプラグインを書くことでCSSを変換することができる。 僕もPostCSSを使って、以前ブログにも書いたAtCSSというCSSプリプロセッサーや、postcss-style-guideというスタイルガイドをMarkdownから自動生成するためのプラグインなどを書いたことがある。

PostCSS製のツールとして、ベンダープレフィックスを自動で付与するAutoprefixerや、現在策定段階でブラウザが未実装のCSSの記法を、今のブラウザが解釈できるようにトランスパイルするcssnextが有名だ。 また、プラグインの一覧はREADMEか、PostCSS.partsというサイトで確認できる。

PostCSSの使い方

PostCSSを使う方法はいくつかあるが、ここではgulpを使ったコード例を示す。

gulp.task('postcss', function () {
    var postcss = require('gulp-postcss');
    return gulp.src('src/**/*.css')
        .pipe( postcss([
            require('postcss-mixins'),
            require('postcss-nested'),
            require('postcss-simple-vars'),
            require('cssnext'),
            require('cssnano'),
        ]) )
        .pipe( gulp.dest('build/') );
});

上記のgulpタスクでは、

の5つのプラグインを使用している。 postcss-nestedは既存のプリプロセッサーにあるセレクタのネスト表記を可能にするプラグインで、postcss-simple-varspostcss-mixinsもそれぞれ変数とミックスインを使用するためのプラグインだ。それらをcssnextと使用し、結果をcssnanoでminifyしている。

結果として、以下のようなコードをコンパイルすることができるようになる。

@define-mixin icon $network, $color: blue {
  .icon.is-$(network) {
    color: $color;
    @mixin-content;
    &:hover {
      color: white;
      background: $color;
    }
  }
}

@mixin icon twitter {
  background: url(twt.png);
}
@mixin icon youtube, red {
  background: url(youtube.png);
}

PostCSSプラグインの作り方

既存のPostCSSのプラグインを組み合わせて使用することもできるが、自分でプラグインを書いて独自のCSSの変換を定義することもできる。

以下はPostCSSのプラグインを書くときのテンプレートだ。 PostCSSのプラグインを書くときは、postcss.plugin()関数をexportする。第一引数にプラグインの名前、第二引数にコールバックとして行いたい変換の処理を記述する。

var postcss = require('postcss');

module.exports = postcss.plugin('PLUGIN_NAME', function (opts) {
    opts = opts || {};
    // Work with options here

    return function (css) {
        // Transform CSS AST here
    };
});

PostCSSのプラグインを書くためのYeomanジェネレーターもあるので、それを使ってもいい。 またガイドラインも用意されていて、プラグイン開発者はそれに従わないといけない。

また、PostCSSではASTを操作するための便利なAPIが用意されている。 どのような操作かはプロパティ名やメソッド名で察してほしいが、node.parentnode.clone()root.eachRule()root.eachDecl()rule.selectorなどがある。 詳しい説明や他のAPIAPIドキュメントがあるので、そちらを見てほしい。

最後に

以前、このブログでもPostCSSはCSSポストプロセッサーをビルドするためのツールだと書いたが、PostCSSは「ポストプロセッサー」という言葉を使わないようにするらしい。少し前からREADMEからはpostprocessorという単語は消えていたが、package.jsonkeywordsからも削除された。 PostCSSのGitHubのissueやGitterでの会話で、PostCSSという名前を変えるべきだという意見もあったので近々名前が変わるかもしれない。

PostCSSの登場やReact.jsの流行により、CSSerにもまた変革が求められているのかもしれない。 しかし解決したい問題は変わってはいないと思うので、問題の本質を知る必要がある。 そのためにも、今自分が使っている技術やツールがどういうものなのかと問いなおすことが重要だ。

その他参考サイト