未来を先取るPostCSS
現在のweb制作はSassを使うのが当たり前になり、もうSassなしでは開発ができないくらいまでに恩恵をもたらしてくれました。 しかし、Sassが登場してから10年がたち次世代CSSの声が聞こえはじめました。 そこで、海外のフロントエンド界隈で普及しつつある、「PostCSS」をgulp環境で使ってみたので、簡単な書き方と概要をまとめました。 デモファイル - GitHub
PostCSSとは
PostCSSとは、JavaScriptで書かれた次世代CSSを変換するためのツールです。 PostCSSは、ES2015を現行のJavaScriptにトランスポートする「Babel」と同じで、未来のcssを現行のcssに翻訳してくれます。 PostCSS自体は、はあくまで変換するツールで、必要な機能をプラグインとして自分で取捨選択し、機能拡張していきます。
PostCSSのメリット
次世代CSSを先取りできることが一番大きなメリットです。 仮に将来、SassやPostCSSが開発終了になっても、そのころにはブラウザが次世代のCSSを読み込めるようになっているはずなので、あらたに何かを探し、勉強する必要はありません。
PostCSSのデメリット
PostCSSは、必要な機能をプラグインとして機能拡張していくといいました。 しかし、これがデメリットをうみます。 というのも、どんどんプラグインを入れていくと自分だけの環境ができあがってしまい、 他の人が読めない・書けないCSSになってしまいます。 なので、プラグインのデファクトスタンダードになりつつある、cssnextに含まれるプラグインのみ使うなどのルールが必要です。 この後の説明もcssnextに含まれるプラグインを中心に、cssnextには含まれていませんが、記法とは直接関係ない便利なプラグインの導入方法をまとめています。
PostCSS導入
すでにgulpを使ってる方は読み飛ばしてください。
gulpの準備
Node.jsのインストール プロジェクトの初期設定
npm init
プロジェクトの初期設定が始まりますが、わからないところはenterで飛ばして、分かるところだけ記入で問題ありません。 gulpのコマンドが使えるように、グローバルインストールします。
npm install -g gulp
次に、プロジェクトディレクトリに移動してローカルインストールします。
npm install —save-dev gulp
これでgulpの設定は完了です。
PostCSSのインストール
gulp用のPostCSS本体をインストールします。
npm install —save-dev gulp-postcss
デモの階層はこんな感じです。
project/
├ htdocs/
│ ├ common/
│ │ ├ postcss/
│ │ └ css/
│ └index.html
│
├ .git/
├ node_modules/
├ gulpfile.js
└ package.json
gulpfile.js に設定を書いていきます。 全体像:
var rootpath = \'htdocs/\';
var cmnpath = rootpath + \'common/\';
var gulp = require(\'gulp\');
var postcss = require(\'gulp-postcss\');
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss())
.pipe(gulp.dest(cmnpath + \'css\'))
});
gulp.task(\'watch\', function(){
gulp.watch(cmnpath + \'postcss/**/*.css\',[\'postcss\']);
});
gulp.task(\'default\', [\'watch\']);
PostCSSのタスクだけ抜き出してみると、非常に単純です。 postcssディレクトリにあるcssファイルを読み込んできて、postcss実行して、cssディレクトリに書き出す。 以上です。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss())
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行
gulp
ですが、このまま実行して、 css/style.css を見てみると postcss/style.css と変化ありません。 それは、PostCSSは本体は何かをするわけではなく、ただツールとしてのAPIを提供しているのでこの結果になりました。 実際の処理はPostCSSのプラグインが行います。
PostCSSのプラグイン
postcss-import
postcss-importは外部ファイルをimportして一つにまとめれるようになります。
インストール
npm install —save-dev postcss-import
gulp.js
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/test.css
h1{
color: #f00;
}
postcss/style.css
@import “test”;
h2{
color: #00f;
}
gulpを実行すると css/style.css
h1{
color: #f00;
}
h2{
color: #00f;
}
このように1つのCSSにまとめることができます。
postcss-custom-properties
postcss-custom-propertiesは変数を使うことができます。
インストール
npm install —save-dev postcss-custom-properties
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
:root {
--color-red: #f00;
--color-green: #0f0;
--color-blue: #00f;
}
h1{
color: var(--color-red);
}
gulpを実行すると css/style.css
h1{
color: #f00;
}
:rootに、変数名の頭に — をつけて定義して、 var(—変数名) で展開します。
postcss-calc
postcss-calcは四則演算ができます。
インストール
npm install —save-dev postcss-calc
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
h1{
font-seze: calc(10*5)px;
font-seze: calc(10px*5);
font-seze: calc(10*5px);
font-seze: calc(10px*5px);
}
gulpを実行すると css/style.css
h1{
font-size: 50px;
font-size: 50px;
font-size: 50px;
font-size: 50px;
}
単位を含んでいてもいなくても計算が可能です。
postcss-selector-matches
postcss-selector-matchesはセレクタをグルーピングできます。
インストール
npm install —save-dev postcss-selector-matches
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\'),
require(\'postcss-selector-matches\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
li :matches(a,i,.red){
color: var(--color-red);
}
gulpを実行すると css/style.css
li a, li i, li .red{
color: #f00;
}
子要素を指定するセレクタです。
postcss-nesting
postcss-nestingはネスト記法が使えます。
インストール
npm install —save-dev postcss-nesting
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\'),
require(\'postcss-selector-matches\'),
require(\'postcss-nesting\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
li{
font-size: 12px;
& a{
color: #f00;
}
}
gulpを実行すると css/style.css
li{
font-size: 12px;
}
li a{
color: #f00;
}
autoprefixer
autoprefixerは「Can I use…」をもとに、ベンダープレフィックスを自動でつけてくれます。
インストール
npm install —save-dev autoprefixer
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\'),
require(\'postcss-selector-matches\'),
require(\'postcss-nesting\'),
require(\'autoprefixer\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
.box{
display: flex;
}
gulpを実行すると css/style.css
.box{
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
postcss-custom-media
postcss-custom-mediaはメディアクエリの定義を変数化できます。
インストール
npm install —save-dev postcss-custom-media
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\'),
require(\'postcss-selector-matches\'),
require(\'postcss-nesting\'),
require(\'autoprefixer\'),
require(\'postcss-custom-media\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
@custom-media --mq_tab screen and (max-width:980px);
@custom-media --mq_mob screen and (max-width:480px);
@media (--mq_tab) {
h1{
color: #00f;
}
}
@media (--mq_mob) {
h1{
color: #0f0;
}
}
gulpを実行すると css/style.css
@media screen and (max-width:980px){
h1{
color: #00f;
}
}
@media screen and (max-width:480px){
h1{
color: #0f0;
}
}
@custom-media —変数名 で定義して @media (—変数名) で展開します
css-mqpacker
このプラグインはcssnextに含まれていませんが、便利なので入れています。 css-mqpackerは散らばったメディアクエリを集めてくれます。
インストール
npm install —save-dev css-mqpacker
gulp.js
上のgulpfile.jsに追記していきます。
gulp.task(\'postcss\', function(){
gulp.src(cmnpath + \'postcss/*.css\')
.pipe(postcss([
require(\'postcss-import\'),
require(\'postcss-custom-properties\')
require(\'postcss-calc\'),
require(\'postcss-selector-matches\'),
require(\'postcss-nesting\'),
require(\'autoprefixer\'),
require(\'postcss-custom-media\'),
require(\'css-mqpacker\')
]))
.pipe(gulp.dest(cmnpath + \'css\'))
});
実行結果
postcss/style.css
@custom-media --mq_tab screen and (max-width:980px);
@custom-media --mq_mob screen and (max-width:480px);
h1{
font-size: 30px;
@media (--mq_tab) {
color: #f00;
}
@media (--mq_mob) {
color: #00f
}
}
h2{
font-size: 20px;
@media (--mq_tab) {
color: #f00;
}
@media (--mq_mob) {
color: #f00;
}
}
gulpを実行すると css/style.css
h1{
font-size: 30px
}
h2{
font-size: 20px
}
@media screen and (max-width:980px){
h1{
color: #f00
}
h2{
color: #f00
}
}
@media screen and (max-width:480px){
h1{
color: #00f
}
h2{
color: #f00
}
}
このようにセレクタに直接メディアクエリを書くことで、修正が簡単になります。 しかし、そのまま出力してしまうとCSSもくちゃぐちゃで、記述が増えてしましますが、このプラグインを通すことでメディアクエリごとにまとまります。
まとめ
現在、Sass 、LESSなどプリプロセッサーがいくつも出ていますが、PostCSSをつかうことで、方向修正がゼロというわけではないですが、最低限で次世代のCSSに対応できるとようになると思います。