はじめに
display: flex を書いたら -webkit-box、-ms-flexbox ……。少し前まで、CSSでモダンな機能を使うたびにベンダープレフィックスを手で並べる作業がついて回っていました。ブラウザごとの対応状況を都度調べ、-webkit-、-moz-、-ms- を書き漏らさないようにする。地味ですが、確実に開発の集中力を奪う作業です。
Autoprefixerは、この作業をまるごと自動化してくれるPostCSSのプラグインです。「Can I Use」の最新データをもとに、対象ブラウザで必要なプレフィックスだけを自動で付け足してくれます。プレフィックスなしのモダンなCSSを書くだけでよくなるので、CSS本来の可読性を保ったまま、ブラウザ互換性の心配から解放されます。
とはいえ、読むより触った方が早いと思います。CSSと対象ブラウザを入力すると、Autoprefixerが実際に変換した結果をその場で確認できるサンプルを用意したので、先に挙動を見たい方はこちらからどうぞ。
Autoprefixerとは
AutoprefixerはPostCSSのプラグインとして動作するツールで、CSSを解析してベンダープレフィックスが必要なプロパティ・値を検出し、対象ブラウザに応じたプレフィックスを自動で追加します。Googleが推奨するツールの一つとしても知られており、TwitterやAlibabaなど大規模サービスの開発でも採用されてきました。GitHub上で22,000以上のスターを獲得し、現在もEvil Martiansによって活発にメンテナンスされています。
主な特徴
- Can I Useのデータに基づく自動判定 - 対象ブラウザで本当に必要なプレフィックスだけを追加し、不要なものは書きません
- browserslistによる対象ブラウザ管理 -
package.jsonや.browserslistrcで対象ブラウザを一元管理し、プロジェクト全体・他のツール(Babelなど)とも設定を共有できます - PostCSSエコシステムとの親和性 -
postcss-preset-envやcssnanoなど他のPostCSSプラグインと組み合わせて使えます - 手書きプレフィックスの自動削除 - 古いプレフィックス付きCSSが残っていても、不要になった分は自動で取り除いてくれます
インストール
npm、Yarn、pnpmのいずれからでもインストールできます。PostCSS本体もあわせて必要です。
npm install -D postcss autoprefixer
yarn add -D postcss autoprefixer
pnpm add -D postcss autoprefixer
Autoprefixerのサンプルを動かす
このサンプルでは、CSSとbrowserslistのクエリを入力すると、Autoprefixerが実際に変換した結果がその場に表示されます。内部ではpostcss([autoprefixer(options)]).process(css)というAPIを使って、入力したCSSに対応するベンダープレフィックスを付与しています。
要点だけを抜き出すと、Autoprefixerの使い方は次のようになります。
import postcss from 'postcss'
import autoprefixer from 'autoprefixer'
const css = `.box {
display: flex;
user-select: none;
}`
const result = await postcss([
autoprefixer({ overrideBrowserslist: ['last 2 versions', 'IE 11'] })
]).process(css, { from: undefined })
console.log(result.css)
実際に動かせるものが下です。CSSや対象ブラウザ(browserslistのクエリ)を書き換えると、その場で出力されるプレフィックスが変わります。
初期状態ではIE 11を含む古めのターゲットを指定しているので、display: flexに-webkit-boxや-ms-flexboxが、user-selectに-webkit-や-moz-が付与されているのが分かります。対象ブラウザの欄をlast 2 versionsだけに絞ると、モダンブラウザ向けの短いプレフィックスだけが残る(あるいはほぼ付かなくなる)様子も確認できます。CSSの欄でbackdrop-filterのように比較的新しいプロパティを試すと、Autoprefixerがどこまで対応しているかも分かります。
基本的な使い方
実際のプロジェクトでは、Autoprefixerはpostcss.config.jsにプラグインとして登録し、Webpack・Vite・Gulpといったビルドツール経由で実行するのが一般的です。
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
],
}
対象ブラウザはoverrideBrowserslistオプションではなく、package.json(または.browserslistrc)のbrowserslistフィールドで指定するのが基本です。こうしておくと、Babelなど他のツールとも対象ブラウザの定義を共有できます。
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
CLIから直接使う場合は、postcss-cliと組み合わせて次のように実行します。
npx postcss style.css --use autoprefixer -o style.prefixed.css
実践的なユースケース
grid オプションでIE向けCSS Gridに対応する
IE 10/11は独自の構文でしかCSS Gridをサポートしていません。Autoprefixerのgridオプションを"autoplace"にすると、モダンなdisplay: gridの記述から、IE向けの-ms-grid-columnsや-ms-grid-rowなどの互換コードを自動生成できます(グリッド線に名前を付けている場合など、一部は自動配置が効かず手動指定が必要になる点は注意が必要です)。
const result = await postcss([
autoprefixer({
overrideBrowserslist: ['IE 11'],
grid: 'autoplace',
})
]).process(`
.layout {
display: grid;
grid-template-columns: 1fr 2fr;
grid-gap: 10px;
}
`, { from: undefined })
下のサンプルでは、gridオプションをfalse(無効)と"autoplace"(自動配置)で切り替えて、出力されるCSSの違いをその場で比較できます。
チェックを外すと-ms-grid-*系のプロパティが消え、IE向けのフォールバックが失われることが分かります。実際にIEをサポート範囲に含めるプロジェクトでは、このgridオプションをオンにしておくかどうかが、レイアウト崩れを防げるかの分かれ目になります。
flexbox オプションで古い仕様のプレフィックスを絞り込む
Flexboxの仕様は策定過程で何度か変わっており、2009年ごろの古い草案(display: boxなど)に対応したプレフィックスも存在します。対象ブラウザにその世代が含まれない場合、Autoprefixerのflexboxオプションを"no-2009"にすることで、古い仕様のプレフィックスを出力対象から除外できます。
const result = await postcss([
autoprefixer({
overrideBrowserslist: ['last 2 versions'],
flexbox: 'no-2009',
})
]).process('.row { display: flex; }', { from: undefined })
以下のサンプルでは、flexboxオプションをtrue(デフォルト、2009年仕様も含む)と"no-2009"で切り替えて出力を比較できます。
チェックを外すとdisplay: -webkit-boxのような古い構文が消え、display: -webkit-flex以降の新しい構文のプレフィックスだけが残ります。対象ブラウザに応じて出力量を絞れるので、生成されるCSSのファイルサイズを抑えたい場合にも役立つオプションです。
まとめ
Autoprefixerは、browserslistで対象ブラウザを定義しておくだけで、CSSのベンダープレフィックスを書く・保守する手間をまるごと肩代わりしてくれるツールです。プレフィックスの付け忘れによる表示崩れを防げるだけでなく、対象ブラウザが変わったときも設定を1箇所直すだけで済むのが大きなメリットです。
すでにWebpackやVite、Tailwind CSSなどのビルドパイプラインに組み込まれていることも多いので、まずは自分のプロジェクトのpostcss.config.jsやpackage.jsonのbrowserslistを確認してみるとよいでしょう。今回のサンプルのように、gridやflexboxといったオプションを調整すれば、対象ブラウザに合わせてより細かく出力を制御できます。