Gulp.jsとPostCSSを使ってCSSの面倒な作業をなくそう

Gulp.jsとPostCSSを使ってCSSの面倒な作業をなくそう

先生

先生

PostCSS

PostCSSはCSSを解析しツリー化してJavaScriptで処理を加えるツールです。
そのため、PostCSS単体ではCSSに何も変化を加えません。Sassのように記述して変形させることもできます。ここではSassでコンパイルされたCSSを、PostCSSを通してSassを拡張するような形で用いていきます。

PostCSS

npm i gulp-postcss --save-dev

gulpfile.jsを以下のように修正します。

gulp.task('css', function () {
    return gulp.src('*.scss')
        .pipe(sassLint())
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError())
        .pipe(sass())
        .pipe(postcss())
        .pipe(csso())
        .pipe(gulp.dest('dest'));
});

この状態でgulp cssを実行しても特に変化はありません。
次にPostCSS用のプラグインであるAutoPrefixerを導入しましょう。

AutoPrefixer

AutoPrefixerはCSSにあるベンダープレフィックスをCan I Useのデータを元に自動的に付与、または不必要なプレフィックスを削除してくれるPostCSSプラグインです。さっそくAutoPrefixerをインストールしてみましょう。

AutoPrefixer

npm i autoprefixer --save-dev

gulpfile.jsを以下のように修正します。
AutoPrefixerのオプションbrowsersにサポートするブラウザの情報を渡します。
下記の例ではブラウザシェアが3%以上あるもの、という指定になっています。
これ以外にもIE9以上(> ie9)などの指定が複数設定できます。

var browsers = [
    '> 3%'
];
gulp.task('css', function () {
    return gulp.src('*.scss')
        .pipe(sassLint())
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError())
        .pipe(sass())
        .pipe(postcss([
            require('autoprefixer')({browsers: browsers})
        ]))
        .pipe(csso())
        .pipe(gulp.dest('dest'));
});

style.scssにベンダープレフィックスが必要なtransformを使った記述を追加してみましょう。

.a {
    &:hover {
        transform: scale(1.2);
    }
}

そしてgulp cssを実行します。

a:hover {
    -webkit-transform: scale(1.2);
    transform: scale(1.2)
}

自動的に-webkitが付与されました。試しにブラウザシェアを50%以上(> 50%)にして実行してみると、以下のようにベンダープレフィックスはつかなくなりました。

a:hover {
    transform: scale(1.2)
}

また、誤って必要のないプレフィックスを付けてしまった場合でも、以下のように

a:hover {
    transform: scale(1.2)
}

と出力され、不必要なプレフィックスは削除されます。
これでどの記述にベンダープレフィックスがいるのか悩む必要がなくなりますね。

doiuse

先ほどはベンダープレフィックスを自動で付与しましたが、そもそもCSS3のプロパティが要件にあったブラウザでサポートされているかどうかはわかりませんでした。
そこでdoiuseというパッケージを使って、指定ブラウザで使えないプロパティがないかどうかを自動的にチェックしてみましょう。

doiuse

npm i doiuse --save-dev

gulpfile.jsを以下のように修正します。

gulp.task('css', function () {
    return gulp.src('*.scss')
        .pipe(sassLint())
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError())
        .pipe(sass())
        .pipe(postcss([
            require('doiuse')({browsers: browsers}),
            require('autoprefixer')({browsers: browsers})
        ]))
        .pipe(csso())
        .pipe(gulp.dest('dest'));
});

ブラウザの指定はAutoPrefixerと同じにしましょう。ブラウザの対応は> 3%にして、gulp cssを実行してみましょう。

gulp css
# [19:59:25] gulp-postcss: style.css
# doiuse: /Users/frontainer/Documents/test/autocss/style.css:4:5: CSS3 2D Transforms not supported by: Opera Mini (5.0-8.0) (transforms2d)
# doiuse: /Users/frontainer/Documents/test/autocss/style.css:5:5: CSS3 2D Transforms not supported by: Opera Mini (5.0-8.0) (transforms2d)
# [19:59:25] Finished 'css' after 721 ms

するとOpera Miniの5.0〜8.0においてはCSS3の2D Transformsはサポートしていないとのことでした。Transformのサポート範囲はわかっていて毎回出るとうっとうしいな、と思ったときにはオプションを以下のようにしてみましょう。

require('doiuse')({
    browsers: browsers,
    ignore: ['transforms2d']
}),

こうすることでtransforms2dの警告が表示されなくなります。一通りサポート状況がチェックできた時点でignoreするかブラウザの設定を見直すようにしましょう。

CSS MQPacker

続いてCSS3のメディアクエリをひとまとめにするパッケージを導入します。
Sassで構築している際にファイルを複数に分けることがありますが、メディアクエリを複数箇所に書いていては、同じ記述が複数回出てきてしまい、無駄が発生してしまいます。そこでMQPackerを導入して同じメディアクエリを1つにまとめましょう。

node-css-mqpacker

npm i css-mqpacker --save-dev
gulp.task('css', function () {
    return gulp.src('*.scss')
        .pipe(sassLint())
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError())
        .pipe(sass())
        .pipe(postcss([
            require('doiuse')({browsers: browsers}),
            require('autoprefixer')({browsers: browsers}),
            require('css-mqpacker')
        ])))
        .pipe(csso())
        .pipe(gulp.dest('dest'));
});

(本当は別ファイルにするのですが、)以下のようなCSSをMQPackerへ通すと、

@media screen and (max-width:800px) {
    .test {
        width: 100px;
    }
}
@media screen and (max-width:800px) {
    .test2 {
        width: 200px;
    }
}

以下のように1つのメディアクエリにまとまります。記述量が減りましたね。

@media screen and (max-width: 800px) {
    .test {
        width: 100px
    }

    .test2 {
        width: 200px
    }
}

まとめ

CSSに関する自動化をご紹介しました。
JavaScriptなどでは当たり前になりつつあった自動化ですが、CSS方面でも広がりを見せています。このような自動化ツールを活用してCSSをチームで統一させたり、より良い書き方を身につけるための練習をしたりしてみてください。

LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。

Webサイト制作の実績・料金を見る

この記事のシェア数

CTOの林です。フロントエンドを専門とし、AngularJSのコミュニティをはじめ、様々な勉強会に顔を出しています。効率化マニアでGrunt,Gulpをはじめ、プロジェクト進行やサーバーサイド、インフラ周りの効率化を目指し日々活動しています。 【役職紹介 / CTO】 Web制作にかかる内容を統括しています。プロジェクトを横断的に見渡し、技術的な見地からアドバイスなどを行い、ときには実制作のヘルプを行ったりしています。新人エンジニアの育成や、体外的な活動としてLIG全体のエンジニアのブランディングのため勉強会やイベントへの登壇・開催なども行っています。 【普段やっていること】 新規サービスの設計(UI,遷移,DB,APIなど)、エンジニアの育成及び環境整備、技術選定、Web制作ユニットの統括とプロジェクト進行を円滑にするための仕組みづくり、フロントエンド周りの実装、エンジニアリングの開発効率化、勉強会の登壇・主催など

このメンバーの記事をもっと読む