PostCSS は ポストCSS の夢を見るか?

この投稿は「Speee Advent Calendar 2016」の16日目です。 前回は弊社CTOによる「1年間、毎月200㎞走ることにコミットした話し」でした。

私はというと、実は風邪を召してしまいました。冬の乾燥にはみなさんもお気をつけ下さい。

PostCSS をかじってみよう

今回は最近何かと話題の PostCSS をかじってみます。

postcss.org

PostCSS は、Pluggable に CSS の文法や機能を拡張できる Node 製のツールです。

PostCSS 自体は CSS を扱う AST (抽象構文木) の相互変換・操作ツールですが、これに対してプラグイン側で CSS に操作を行うことで、CSS のみではできない機能を付加します。CSS 操作系ツールでは、内部で PostCSS が使われている例も多く、現在の CSS 操作の主流となっています。

使用例

CSS 周りの歴史

まずは CSS 周りの歴史 を軽くおさらい。

  • 2006
    • Sass の登場
      • SASS 記法の採用(インデントブロック)
      • SassScript (変数、式、セレクタのネスト、mixinなど)
  • 2009
    • LESS の登場
      • CSS と互換性のある記法
      • JavaScript 製、Bootstrap 2・3で採用
  • 2010
    • Sass v3 の登場
      • SCSS 記法 (Sassy CSS)の採用
      • Bootstrap 3・4で採用
    • Stylus の登場
      • SASS 記法と CSS 互換の記法のハイブリッド
    • Compass の普及 (現在はサポート終了)
      • ベンダープレフィックスの付加が楽に
  • 2013
    • autoprefixer の登場
      • 指定した対応ブラウザに応じてプレフィックスを付与
  • 2014
  • 2015
    • Sass の人気が LESS を追い越す (2015年9月)
    • PostCSS v5 の登場

自身の周りで PostCSS が注目され始めたのは、Bootstrap 開発者が Bootstrap 5 での採用を示唆した頃と記憶しています。まだ 4 も alpha なのに...

導入

yarn で導入していますが、npm でも構いません。

$ yarn init
$ yarn add postcss postcss-cli --dev

今回はパッケージスクリプトで動作させるため、postcsspostcss-cli を導入しました。この関係性は、babelbabel-cli の関係性に近いです。

もし gulp で使うなら gulp-postcss を、Webpack を使うなら postcss-loader を使用できます。

package.json

{
  "private": true,
  "scripts": {
    "postcss": "postcss -c ./postcss.json"
  },
  "devDependencies": {
    "postcss": "^5.2.6",
    "postcss-cli": "^2.6.0"
  }
}
$ yarn run postcss -- -o after.css before.css

以上のコマンドで、before.css を PostCSS で変換し after.css に出力できるようになります。

設定は、外部の JSON postcss.json から使用するように設定しました。

例:autoprefixer を使用する場合

$ yarn add autoprefixer --dev
postcss.json
{
  "use": ["autoprefixer"],  // 使用するプラグイン
  "local-plugins": "true",  // node_modules フォルダを使用

  // autoprefixer の設定
  "autoprefixer": {
    "browsers": "Last 2 versions"
  }
}

監視させる

-w オプションを使用することで、Sass や LESS のようなファイル監視も可能です。

$ yarn run postcss -- -w -o after.css before.css

プラグイン

PostCSS のプラグインはできることが非常に多く、それぞれのプラグインごとに1つ記事が書けるぐらいです。パッケージとして纏まっているものについて、それぞれ概略を。

autoprefixer

github.com

指定した対応ブラウザに応じたベンダープレフィックスを付与するプラグインです。サポートするブラウザを明示でき、Commpass のように無駄なベンダープレフィックスが付与されないのが特徴です。

cssnext

f:id:yuki-hattori:20161216223410p:plain:w300

cssnext - Use tomorrow’s CSS syntax, today.

W3C で策定中、あるいは策定候補に入っている新しい構文を、旧ブラウザ向けに fallback して使えるようにしてくれるプラグイン群です。立場としては Babel に近い存在です。オンラインでも試せます。

ただ、Babel のようなプリセットは無く、CSS の機能策定は各機能ごとに進められるため、PostCSS でプラグインごとに個別管理するのが良いのでは?という意見もあります。(参考: PostCSS とは何か // Speaker Deck)

PreCSS

f:id:yuki-hattori:20161216224656p:plain:w300

PreCSS

CSS の文法を維持したまま、変数、セレクタのネスト、mixin、extend、条件分岐、ループなどが書けるようになるプラグイン群です。Sass や LESS などの、プリプロセッサの処理に取って代わるものです。

PostCSS v5 より、postcss-scss などのパーサーを併用することで、Sass 記法を直接扱ったりすることも可能です。

cssnano

f:id:yuki-hattori:20161216224944p:plain:w300

cssnano: A modular minifier based on the PostCSS ecosystem.

CSS の minify に特化したプラグイン群です。以下のように圧縮されます。(公式より引用...)

@charset "utf-8";h1:before{margin:10px 20px;color:red;border-radius:16px;font-weight:normal;background-position:100% 100%}

企業での採用例も多いのが特徴。

CSS Modules

f:id:yuki-hattori:20161216230616p:plain:w300

https://github.com/css-modules/css-modules

CSS のクラスをユニークな名称に置換することで、CSS の記述をモジュール化します。ある意味 Web Components の先取りとも言えるもので、React とも相性が良いです(参考: CSSモジュール ― 明るい未来へようこそ | プログラミング | POSTD)。

stylelint

stylelint.io

スタイルシートに対する Linter です。ESLint ライクにルールの設定が可能です。

stylefmt と併用することで、自動修正も可能になります。ちなみに日本製。

PostCSS は ポストCSS の夢を見るか?

導入すべきか

プロジェクトでの実践投入はまだ実施していませんが、実は PostCSS と知らず知らずの間に使っていた ライブラリも結構多く (autoprefixer、CSS Modules など)、CSS のモダン化においては stylelint や cssnano なども積極採用しても良さそうな印象を受けました。

一方、PreCSS の記法などを採用するかと言えばそうではなく、今のところはまだまだ Sass や LESS の記法にお世話になると思われます。特にデザイナーの文脈では、記法がすでに確立されているというアドバンテージは大きいので。

CSS のモダン

フロントエンドのモダン化は、現行のプロジェクトで進めているものの、どうしても JavaScript が先んじていて、CSS は後手に回りがちです。が、処理速度や拡張性の点で、メリットが大きいのも確かです。

個人的なプロダクト (Marp など) では、まずは Sass を崩さない範囲で実験的に PostCSS を導入していこうと思っています。


次回は @arumi8go です。