プログラミングスクールやウェブ制作会社の HP では、CSS のベンダープレフィックスについて未だ時代遅れな内容が最新記事として配信されているのが散見されます。
これらの内容を鵜呑みにすると、効果のない余計なコードを書いて消耗することになりかねません。
そこで当記事では、今の CSS で本当に必要且つ正しいベンダープレフィックスの知識を整理しました。
そもそもベンダープレフィックスとは
ベンダープレフィックス(vendor prefix、以下 プレフィックスとする)とは、ブラウザが試験的、又は独自に実装した機能を表すために CSS のコードの先頭につける文字列のことです。
今の CSS で使われるのは以下の 2 つです。
-webkit-: Chrome や Safari 向け-moz-: Firefox 向け
書く順番のルール
同じ機能にプレフィックス有りの試験実装とプレフィックス無しの正式実装がある場合、「有り」 を先に書き、その下に「無し」を書く必要があります。
CSSは下に書いた記述が優先されるのが原則です。逆に書いてしまうと「無し」の正式実装が無視されてしまうので注意して下さい。
プロパティで使う時(書き方の例)
selector{
-webkit-appearance: none;
-moz-appearance: none;
appearance: none; /* 正式実装 */
}
プロパティで使う時は、基本的に名前の先頭にプレフィックスを付けます。
上記の appearance ならば -webkit-appearance のようになります。
appearance は、現在主要ブラウザがプレフィックス無しに対応しているため、上記のルール通り「無し」の記載を下に書きます。
プロパティの値にも同じく先頭に付けてプレフィックスを使えますが、使用頻度が極めて低いため説明は省略します。
疑似クラスで使う時(書き方の例)
selector::-webkit-scrollbar{ background-color: skyblue; }
疑似クラスで使う時は、基本的に「::」又は「:」のすぐ後にプレフィックスを付けます。
上記の ::scrollbar ならば ::-webkit-scrollbar のようになります。
::scrollbar は正式実装されていないため、プレフィックス有りのみ必要です。
アットルールで使う時(書き方の例)
@-moz-document url-prefix(){
selector{ property: value; }
}
アットルールで使う時は @ のすぐ後ろにプレフィックスを付けます。
上記の @document ならば @-moz-document のようになります。
@document は Firefox 独自の試験実装で正式化されなかったため、-moz- のプレフィックス有りのみ必要です。
現在プレフィックスが必要なもの(プロパティなど)
今の CSS でプレフィックスが必須又は付けるべきなのは、これら以外にもありますが、主に以下の 7 つです。
殆どの機能は最初からプレフィックス無し、あるいはプレフィックス不要となりました。
また、プレフィックスの付け方やブラウザ対応は Can I use... などで必ず個別に調べる必要があります。
Can I use... Support tables for HTML5, CSS3, etcappearance
selector{
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
HTML の入力要素(input、textarea、select タグ)に付く、ブラウザのデフォルトスタイルの有無を指定するプロパティです。値を none にするとデフォルトスタイルを消すことができます。
今は主要ブラウザがプレフィックス無しで対応したため、いずれプレフィックス不要になるでしょう。
text-size-adjust
selector{
-webkit-text-size-adjust: 100%; /* Safari で必須 */
-moz-text-size-adjust: 100%; /* Firefox で必須 */
text-size-adjust: 100%; /* Chrome 向け */
}
主にスマホのブラウザの横向き画面の文字サイズ自動調整を制御するプロパティです。
特に iPhone の Safari で画面を横向きにすると文字が大きくなってしまいますよね。
text-size-adjust の値を 100% にすることで自動調整を無効化できます。none だとバグのリスクがあるため 100% が望ましいです。
text-stroke(-webkit-~)
selector{
-webkit-text-stroke: 2px red; /* -webkit- が必須。Firefox も -webkit- */
}
文字に縁をつけるプロパティです。
-webkit- が付いたまま 主要ブラウザが揃って対応したプロパティです。
正式実装されていないためプレフィックス有りのみ必要です。
user-select
selector{
/* -moz-user-select は不要 */
-webkit-user-select: none; /* Safari で必須 */
user-select: none;
}
テキストの選択を制御するプロパティです。値を none にするとテキストの選択を禁止できます
-moz-user-select は存在しますが、Firefox は既にプレフィックス無しで対応済のため不要と見ていいでしょう。
user-drag
selector{ -webkit-user-drag: none; /* -webkit- が必須 */ }
画像やテキストなどの要素をドラッグして引っ張る動作を制御するプロパティです。値を none にするとドラッグを禁止できます。
今は FireFox が未対応のため、-moz-user-drag は存在しません。
::scrollbar(::-webkit-~)
/* スクロールバーの背景 */
selector::-webkit-scrollbar{ background-color: skyblue; }
/* スクロールバーのつまみ */
selector::-webkit-scrollbar-thumb{ background-color: darkblue; }
スクロールバーのスタイルを設定する疑似クラスです。::scrollbar がスクロールバーの背景、::scrollbar-thumb がスクロールバーのつまみを指します。
Firefox はこの疑似クラスに対応していません。
正式実装されていないためプレフィックス有りのみ必要です。
@document(@-moz-~)
/* Chrome や Safari は無視 */
@-moz-document url-prefix(){
/* Firefox だけこの中を認識 */
selector:before{ content: 'あなたのブラウザは Firefox ですね!'; }
}
Firefox だけ任意のスタイルを適用したい時に使うアットルールで、ブラウザが Firefox がどうか判定するのにも使えます。
@document (@-moz-document)は、かつて Firefox が URL で CSS を切り替える機能を独自に試験実装したものですが、正式化せず廃止されました。
しかし @-moz-document url-prefix() だけ Firefox 識別用に対応が残されたという特殊経緯があります。
-ms- や -o- はもう不要
プログラミングスクールやウェブ制作会社の HP などのウェブ記事では新旧関わらず「-ms-」や「-o-」というプレフィックスが多数出てきます。個人ブログですと稀に「-khtml-」も...。
しかし、これらは過去の遺産であり、今の CSS にはもう必要ありません。
-ms- は IE 系列だけのもの
-ms- はかつて Microsoft のブラウザ「Internet Explorer (IE)」系列のためのプレフィックスでした。
IE には、以下のような独自機能や、今のブラウザと異なる実装が存在しました。
/* IME の位置を入力欄の下にする独自機能 */
selector{ -ms-ime-align: after; /* IE11、Legacy Edge */ }
/* かつてのグリッドレイアウト */
selector{
display: -ms-grid; /* IE10~、Legacy Edge */
display: grid; /* 今の正式実装 */
}
ブラウザの歴史を辿ると IE 系列のブラウザが終わりを迎えた経緯があります。
- 2021年: Microsoft は、IE の後継であり、-ms- と -webkit- の両方が使えた、旧 Edge(Legacy Edge)のサポートを終了。
Edge の中身を Chrome ベース(Blinkエンジン)に丸ごと置き換え。
これにより、Edge で -ms- は使えなくなり、Chrome と同じ-webkit-が使われるようになりました。 - 2022年: IE のサポートも終了しました。
つまり、-ms- はもう役目を終えたプレフィックスなのです。
-o- は古の Opera だけのもの
-o- はかつて Opera Software のブラウザ「Opera」専用のプレフィックスでした。
過去には以下のように -o- が必要なプロパティもありました。
selector{
-webkit-transition: .5s linear;
-moz-transition: .5s linear;
-o-transition: .5s linear; /* ~Opera 12(2012 年)まで */
transition: .5s linear; /* 今必要な記述はこれだけ */
}
Opera はかつて独自エンジン(Presto)を採用しており、-o- を使うことができました。
- 2013 年: Opera は独自エンジンの開発を断念。
Chrome ベース(Blink エンジン)に切り替え。
これで -o- は使えなくなり、代わりに Chrome と同じ-webkit-に対応しました。
それから時が過ぎた今、2012 年の独自エンジン時代の Opera に対応する必要性は 1 mm もありません。
-o- はもはや古の遺産なのです。
-khtml- は最初期の Safari のもの
-khtml- かつて Apple の Mac 用ブラウザ Safari の最初期に対応していたプレフィックスです。
以下は実際に存在した記述例です。
selector{
-khtml-opacity: .5; /* ~Safari 1(2006 年)まで */
opacity: .5; /* 今必要な記述はこれだけ */
}
その後、Safari で -khtml- が使えたのは 2006 年頃までで、それ以降は -webkit- に変わっています。
それから長い年月が過ぎた今、2006 年の Mac の Safari は必要ないどころか現存しません。
ネットの記事に稀にこれが混ざっていることがありますが、-khtml- は説明するまでもない竹槍レベルの古の遺産です。
未だプレフィックスが書かれがちなもの
以下の機能は、プレフィックス付きの記述が並んだネット記事が結構ありがちです。
しかし、今のブラウザでは、これらはプレフィックス無しの記述だけ書けばきちんと動きます。プレフィックスを並べても記述とファイルの容量が無駄に増えるだけです。
transform...要素の変形・回転・拡大などtransition...要素の変化をなだらかにするanimation・@keyframes...JS 不要のアニメーションfilter...要素のぼかしや色調補正object-fit...画像のトリミング表示linear-gradient()...色のグラデーション- グリッドレイアウト(
display: grid;) ...四角い自由レイアウト(グリッドレイアウト) - フレックスボックス(
display: flex;) ...横並びレイアウト
プレフィックスの個別確認をしないと嵌る罠
プログラミングスクール HP などのネット記事では、あたかも標準コードの頭にプレフィックスをひたすら並べて付ければ OK!と思わせるような解説が目立ちます。中には、堂々と間違ったコードを載せている記事すらあります。
ここに大きな罠が潜んでいます。
-webkit-、-moz-、-ms-、-o- を闇雲に並べても、互換性が上がるどころか、CSS の歴史上存在しないゴミコードを増やすだけになりかねません。
ここからは、実際に罠にハマりやすい間違い例と、正しい記述を見ていきます。
appearance: -ms- や -o- は存在しない
前述した通り、appearance に存在するプレフィックスは -webkit- と -moz- の 2 つだけです。しかし、ネットの記事では、存在すらしない -ms- や -o- まで 4 つフルで書かれているケースも少数あります。
/* ❌ 間違い例 */
selector{
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none; /* ❌ 存在しない → Legacy Edge は -webkit-、IE 非対応 */
-o-appearance: none; /* ❌ 存在しない! → Opera は -webkit- */
appearance: none;
}
/* ⭕ 正しい例 */
selector{
-webkit-appearance: none; /* 💡 Legacy Edge も Opera もここで対応 */
-moz-appearance: none;
appearance: none;
}
フレックスボックス: 度重なる仕様変更
フレックスボックス(display: flex;)は要素を横並びにする便利な機能ですが、これは頭にプレフィックスを付けるだけだと、存在しないゴミコードを羅列しかねない罠があります。
今はプレフィックス不要となりました。
フレックスボックスは 3 段階もの度重なる仕様変更があったため、かつては頭に記号をつけるだけでなく、名前そのものを別々に記述する必要があったのです。
しかし、ネットの記事では、存在しない display: -ms-flex; のような出鱈目が書かれているケースが少数あります。
/* ❌ 間違い例 */
selector{
display: -webkit-flex;
display: -moz-flex; /* ❌ 存在しない → FireFox は -moz-box */
display: -ms-flex; /* ❌ 存在しない!→ IE は -ms-flexbox */
display: -o-flex; /* ❌ 存在しない!!→ Opera は -webkit- */
display: flex;
}
/* ⭕ かつて必要だった記述の正しい例 */
selector{
/*【第一世代】display: box;
** Chrome・Safari・Firefox(2008 ~ 2012 年辺り)** */
display: -webkit-box;
display: -moz-box;
/*【第二世代】display: flexbox;
** IE10(2012 年)** */
display: -ms-flexbox;
/*【第三世代】display: flex;
** 💡 Opera は最初からこれ ** */
display: -webkit-flex; /* 2013 ~ 2014 年辺り */
display: flex; /* 正式実装: 今必要な記載はこれだけ */
}
linear-gradient() : ただ付けるだけは絶対 NG!
背景をグラデーションにする linear-gradient() も、頭にプレフィックスを付けるだけではまず動かず、フレックスボックスより複雑な罠コードです。
こちらも今はプレフィックス不要ですが、かつて Safari に独自の別名があったり、グラデーションの方向指定が違ったり、IE は 9 以前にはプレフィックスどころか謎の呪文(笑)を長々と書く必要があったりしました。
/* ❌ 間違い例 */
selector{
background-image: -webkit-linear-gradient(to bottom, #000000, #FFFFFF); /* ❌ 開始位置じゃないと動かない */
background-image: -moz-linear-gradient(to bottom, #000000, #FFFFFF); /* ❌ 開始位置じゃないと動かない! */
background-image: -ms-linear-gradient(to bottom, #000000, #FFFFFF); /* ❌ 存在しないって! */
background-image: -o-linear-gradient(to bottom, #000000, #FFFFFF); /* ❌ だから開始位置じゃないとダメだって! */
background-image: linear-gradient(to bottom, #000000, #FFFFFF);
}
/* ⭕ かつて必要だった記述の正しい例 */
selector{
/* IE5.5 ~ 9 (2000 ~ 2011 年) ** #[透明度 2 桁][色 6 桁] ** */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF000000', endColorstr='#FFFFFFFF', GradientType=0);
/* Safari5 ~ 6 の試験実装(2012 年)*/
background-image: -webkit-gradient(linear, left top, left bottom, from(#000000), to(#FFFFFF));
/* Chrome・Opera・Firefox の試験実装(2011 ~ 2013 年辺り)** 方向を開始位置で指定 ** */
background-image: -webkit-linear-gradient(top, #000000, #FFFFFF);
background-image: -moz-linear-gradient(top, #000000, #FFFFFF);
background-image: -o-linear-gradient(top, #000000, #FFFFFF);
/* 今必要な記載はこれだけ ** 方向を終端位置で指定 ** */
background-image: linear-gradient(to bottom, #000000, #FFFFFF);
}
結論: プレフィックスの付け方は機能によって全く異なる
ここまで見てきたように、プレフィックスの付け方の個別確認が必須な理由は、その機能ごとに、必要な記号や当時の仕様がバラバラだからです。
プレフィックスを書くということは、単に記号を頭に付けるだけではありません。本質的には、その機能が試験実装だった時代に合わせてコードを別物として書き換えることなのです。
そのため、現代のコードの頭にプレフィックスを並べるだけでは、以下のような結末を迎えます。
- 存在しないゴミコードの羅列でファイルの容量が無駄に増加
- 今と仕様が違うため当時のブラウザでプレフィックス有りのコードが 1 mm も動かない
そして最大の罠は、現代において、ベンダープレフィックス必須だった当時の古いブラウザで実際に検証する機会がほぼゼロという点です。
だからこそ、ネットの記事も、貴方のコードも、間違いに気づけないまま放置されるのです。