ブラウザの進化が早い昨今、CSSのベンダープレフィックス(-webkit-
や-ms-
)が必要なプロパティと不要なプロパティが入り乱れています。必要なベンダープレフィックスのみを付与しようとした場合、途端にコード量が倍増し、メンテナンス性が低下し、バグの温床となります。このベンダープレフィックス地獄を解消するAutoprefixerをGulpやwebpackで使う方法を紹介します。
今なお続くベンダープレフィックス地獄
角丸を表現するborder-radius
プロパティはIE 11を含む全ての主要ブラウザで、ベンダープレフィックス無しで使えます。(Can I use border-radius)
一方で、ボックスレイアウトモジュールの為のflexbox
プロパティやテキスト要素を変形するtransform
プロパティ等では、Android 4.4以下等一部のブラウザではベンダープレフィックスが必要です。
しかし、毎日刻々と変化するブラウザの仕様を追い続け、必要なベンダープレフィックスだけを付与していくのは大変な労力です。また、ベンダープレフィックスを全てつけて解決を試みるコードを見かけます。確かにブラウザによるレイアウト崩れは防げるものの、一つの値を編集するだけで通常の何倍もの作業が発生し、ストレスとタイピングミスが増えるので辞めるべきです。
div {
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
}
ベンダープレフィックス地獄を解決するAutoprefixer
これらのベンダープレフィックス地獄はAutoprefixerを使うことで解決できます。Autoprefixerは最新のブラウザ実装状況をまとめたサイト「Can I use」の情報を使用し、必要なベンダープレフィックスのみを付与する為のツールです。
また、ベンダープレフィックスの適用範囲を細かく指定することが可能で、例えば下記のような指定ができます。
- 各ブラウザの最新バージョンと一つ前のバージョンで必要なベンダープレフィックスのみ
- IEは11以上、Android標準ブラウザは4以上で必要なベンダープレフィックスのみ
- シェアが5%以上のブラウザで必要なベンダープレフィックスのみ
簡単な変換を通して、Autoprefixerの設定手順を紹介します。
変換用のCSS
プロジェクトフォルダにsrc
フォルダを作成し、テスト用のstyle.cssファイルを作成します。
projectFolder/
└ src/
└ style.css
style.cssの中には下記のようなスタイルを設定しました。border-radius
プロパティやdisplay
プロパティに、自動で必要なベンダープレフィックスを付与します。
main {
border-radius: 5px;
display: flex;
}
Autoprefixerはwebpack、Gulp、CLIなど様々な環境で使えます。本エントリーではwebpackとGulpでの設定方法について解説します。自身の環境にあったものをご覧ください。
GulpでAutoprefixerを使う
この章ではGulpとの連携方法について解説します。Gulpの詳しい導入方法や使い方については記事「絶対つまずかないGulp入門(2018年版) – インストールとSassを使うまでの手順 - ICS MEDIA」を参照してください。
環境のセットアップ
プロジェクトフォルダにて、下記コマンドを使って初期化します(※1)。
npm init -y
必要なモジュールをインストールします。Autoprefixerは「PostCSS」の一部なので、本体「autoprefixer」とあわせてGulpでPostCSSを使うための「gulp-postcss」をインストールします。
npm i -D gulp gulp-postcss autoprefixer
※ Gulp用のAutoprefixerプラグイン「gulp-autoprefixer」もありますが、こちらは暫くメンテナンスされておらず、内部で使われているAutoprefixerは古いです。
タスクの定義
Gulpタスク用にgulpfile.jsを作成して下記のタスクを定義します。☆部分がベンダープレフィックスをどのように設定するかを指定する部分です。他の指定方法は「BrowserslistのREADME」を参照するとよいでしょう。例えば、「IE 11以上、Androidは4以上、その他は2バージョン」を指定してみます。
const gulp = require("gulp");
const postcss = require("gulp-postcss");
const autoprefixer = require("autoprefixer");
gulp.task("default", function () {
return gulp.src("src/style.css")
.pipe(postcss([
autoprefixer({
// ☆IEは11以上、Androidは4.4以上
// その他は最新2バージョンで必要なベンダープレフィックスを付与する設定
browsers: ["last 2 versions", "ie >= 11", "Android >= 4"],
cascade: false
})
]))
.pipe(gulp.dest("dist"));
});
上記のタスクを実行するには、下記コマンドを使います(※2)。
$ npx gulp
必要なベンダープレフィックスが付与された
Autoprefixerが適用されたCSSは下記です(上記のタスクでdist
フォルダにstyle.cssが書き出されます)。border-radius
プロパティはベンダープレフィックスが付与されず、flex
プロパティのみに必要なベンダープレフィックスが付与されます。
main {
border-radius: 5px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
ちなみに、browsers: [(中略), "ios_saf >= 8"],
のように、iOS Safari 8を対象にした場合、-webkit-flex
と旧仕様のプロパティが追加されます。
main {
border-radius: 5px;
display: -webkit-box;
display: -webkit-flex; /* 旧仕様が追加された */
display: -ms-flexbox;
display: flex;
}
webpackでAutoprefixerを使う
この章ではwebpackとの連携方法について解説します。webpackの詳しい導入方法や使い方については以下の記事も参照ください。
webpackの初期設定では、src
フォルダのindex.js
でimport
した各ファイルをバンドル(一つにまとめること)します。次のようにindex.js
を追加します。
projectFolder/
└ src/
└ style.css
└ index.js
index.js
内でCSSファイルを読み込みます。
// import文を使ってCSSファイルを読み込む。
import './style.css';
プロジェクトフォルダにて、下記コマンドを使って初期化します。
npm init -y
必要なモジュールをインストールします。Autoprefixerは「PostCSS」の一部なので、本体「autoprefixer」とあわせてGulpでPostCSSを使うための「postcss-loader」をインストールします(※1)。
npm i -D webpack webpack-cli style-loader css-loader postcss-loader autoprefixer
webpack.config.jsの定義
webpack.config.jsを作成し、下記の設定を記述します。☆部分がベンダープレフィックスをどのように設定するかを指定する部分です。他の指定方法は「BrowserslistのREADME」を参照するとよいでしょう。例えば、「IE 11以上、Androidは4以上、その他は2バージョン」を指定してみます。
module.exports = {
mode: "development",
module: {
rules: [
{
test: /\.css/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
url: false,
importLoaders: 1
},
},
// PostCSSのための設定★
{
loader: "postcss-loader",
options: {
plugins: [
// Autoprefixerを有効化
require("autoprefixer")({
// ☆IEは11以上、Androidは4.4以上
// その他は最新2バージョンで必要なベンダープレフィックスを付与する設定
browsers: ["last 2 versions", "ie >= 11", "Android >= 4"]
})
]
}
}
]
}
]
}
};
下記コマンドでwebpackを実行すると、Autoprefixerによるベンダープレフィックスの自動付与が行われます。
npx webpack
必要なベンダープレフィックスが付与された
Autoprefixerが適用されたCSSは下記です。dist
フォルダのmain.js内のCSS部分をぬきだしたものです。
main {
border-radius: 5px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
ParcelでAutoprefixerを使う
ParcelでAutoprefixerを使う方法については、次の記事を参照ください。webpackやGulpの場合と異なり、設定ファイルが不要なのでラクです。
対象ブラウザは外部ファイルに記述もできる
webpack、Gulpの場合共に、対象ブラウザはpackage.json
や.browserslistrc
というファイルに記述することも可能です。Autoprefixer以外のツールと対象ブラウザの設定を共有したい場合に役立ちます。この場合はwebpack.config.js
やgulpfile.js
でのブラウザ指定は不要です。
package.json
の場合
{
"dependencies": {
"autoprefixer": "^8.6.4"
},
"browserslist": [
"last 2 versions",
"ie >= 11",
"Android >= 4"
]
}
.browserslistrc
の場合
> 0.5%
last 2 versions
ie >= 11
Android >= 4
Grid対応も強力
CSS GridでIE 11対応をする場合も、Autoprefixerは強力です。次の記事で詳しく解説しましたので参照ください。
- AutoprefixerがパワーアップしてCSS GridのIE 11対応がバリ楽になってた - Qiita
- CSS Gridのgap(grid-gap)が遂にIE 11でも再現できるように。Autoprefixerが待望のアップデート
もうベンダープレフィックスで消耗するのは辞めましょう
美しいCSSコードとは、ベンダープレフィックスが必要最低限だけ付与されたコードです。Autoprefixerに出会う前は、逐一プロパティ毎のベンダープレフィックス必要性を調べ、適用していくという大変な苦労を強いられました。Autoprefixerを使って面倒なベンダープレフィックスの処理は全て自動化し、ストレスとタイピングミスから解放されたCSSコーディングを今日から行いましょう。
※1 -y
や-D
について不明であれば、GulpやSassを使う時に覚えて幸せになったnpmの便利な使い方を参照ください。
※2 npxについて不明であれば、「npm 5.2.0の新機能! 「npx」でローカルパッケージを手軽に実行しよう 」を参照ください。