自分のサイトのSCSSをPostCSSに書き換えたので、そのときに調べたことをメモしておく。プラグインパックであるcssnextはなにがどう変換されているか把握できなくなりそうなので使わずに、個別でインストールしていく方針。どんなサイトでも基本的に使うだろうな、というものだけメモしておく。
ここで書いたもので不足を感じたときにReadmeに書かれているものなりPostCSS.partsにあるプラグインを試せばいいとおもう。ただ最後にもすこし触れるけど、なんでも便利そうだからと入れて使うのはやめたほうがいいとおもう。
SCSSからの移行であればprecssがよさそう。ただ自分が使ったときはcssnanoと併用したときに、importしたファイルをうまくminifyできていませんでした。
プラグイン
記法
postcss-import
@import
したファイルを展開する。最初によみこまないと以降に紹介するpostcss-simple-varsやpostcss-mixinsをimportしたときエラーになるので、最初に読み込ませておく。
postcss-simple-vars
SCSSっぽいシンプルな$
を使った変数が使える。使い方は大体同じ。
$theme-color0: #fff;
$body-bgcolor: $theme-color0;
$font-family-base: Meiryo, Arial, sans-serif;
$font-family-heading: 'Hiragino Kaku Gothic ProN', $font-family-base;
変数をプロパティの値以外で使うときにはSCSSとはちょっとだけ記法が違う。
$name: Box;
.$(name)-list { }
.Box-list { }
変数のスコープは以下のような挙動になり特に警告がでるようなこともないので、LESSからの移植の場合注意が必要になるかもしれない。
$color0: #000;
.foo {
$color0: #fff;
color: $color0;
}
.bar {
color: $color0;
}
.foo {
color: #fff;
}
.bar {
color: #fff;
}
この挙動が問題になるのであればpostcss-nested-varsを使うというのもいいかもしれない。
JavaScriptに設定を持たせることもできる。CSS Modulesで使いやすいのだろうか、普通のCSSでそういった使い方をすることはあんまりないとおもう。
その他の変数のためのプラグイン
これらは仕様に近い記述ができます。
:root {
--theme-color0: #fff;
--body-bgcolor: var(--theme-color0); /* postcss-css-variablesではエラー */
--font-family-base: Meiryo, Arial, sans-serif; /* たぶんどちらでもエラー */
}
こういった記述のほかにもプロパティの値以外で変数が使えなくなるというのもちょっときついかな、と思う。仕様的にはすくなくとも上は問題なかったはず。下はちょっと怪しいので普通にextendするべきかな。
どうしてもこだわりがあるのであれば、postcss-media-variablesやpostcss-font-packといったものも使わないと使いにくそうだなと感じた。ただpostcss-font-packはpostcss-importとうまく使えなかった。使う予定はなかったのであまり詳しく調べたりはしなかった。
postcss-nested
SCSSでもあるCSSの入れ子。
.cats {
&-list {
list-style-type: none;
.cat {
margin: 1rem;
}
}
.container & {
margin: 0;
}
}
.cats-list {
list-style-type: none;
}
.cats-list .cat {
margin: 1rem;
}
.container .cats {
margin: 0;
}
postcss-mixins
mixinsを使える。SCSSよりも便利なところは以下のようなことができるところ。
@define-mixin foo {
&::after {
content: "foo";
}
}
LESSでもこの記述は問題なく可能なので、twbs4でもLESSからSCSSへの移植でこのあたりの記述がかなりゴチャゴチャになってた気がする。
postcss-extend
placeholderを使える。
@define-placeholder simple-list {
list-style-type: none;
}
.cats-list {
@extend simple-list;
}
.dogs-list {
@extend simple-list;
}
.cats-list, .dogs-list {
list-style-type: none;
}
postcss-color-function
仕様と同じのcolor
関数。
.foo {
color: color(#000 a(10%));
background-color: color(#000 l(50%));
border-color: color(#fff b(50%));
}
.foo {
color: rgba(0, 0, 0, 0.1);
background-color: rgb(128, 128, 128);
border-color: rgb(170, 170, 170);
}
postcss-calc
calc
関数。
$foo: 20px;
.foo {
width: calc($foo * 2);
height: calc(20% - $foo);
}
.foo {
width: 40px;
height: calc(20% - 20px);
}
postcss-comment
//
のコメントアウト。
// コメント
/* コメント */
その他
だいたい以下の2つとpostcss-importは毎回確実に使っています。
autoprefixer
説明は不要であろうautoprefixer。
CSSWring
CSSのminify。autoprefixerなどの機能もついているcssnanoなんかもあるんだけれど、プラグインの機能は多くありすぎても使いにくいので、cssnanoは使わずにCSSWringを使っています。
なぜPostCSSを使うのか
自分がPostCSSを使う理由は変換の早さではなくて、SCSSやLESSの多機能性を求めていなかったことにあるとおもう。特に最近はJSXとか.vueとかPolymerなんかでCSSをコンポーネント化することが多くて、まずネストは使わなくなるし、変数すら使わなかったりする。Polymerなんかは変数もmixinも自身の機能として提供されているしね。変数のプラグインで使うにしてもSCSSライクなものよりは仕様通りのものを使ってくれていたほうがありがたいかなあとおもう。
ただ、かといってCSSをそのまま書くのはどうせautoprefixerは使うし、minifyもするし、importでconcatはしてほしいし、場合によってはextendやcolorも使いたい。そういうわけでそのあたりを一括でプラグインで管理できるPostCSSが便利だなーと感じて最近ではPostCSS以外使うことはなくなりました。
PostCSSでprecssやnextcssに加えてプラグインをあれもこれもと大量に導入して……なんてやるならたぶん素直にSCSSやLESS、Stylusなんかを使ったほうがいいんじゃないかなーという気はします。すくなくともそういうCSSを自分は見たいと思わない。