フレックスボックスの後方互換性

フレックスボックスは最新のブラウザーではとてもよく対応されていますが、いくつかの問題に遭遇する可能性があります。このガイドでは、フレックスボックスがブラウザーでどの程度対応されているかを見て、いくつかの潜在的な問題、リソース、回避策やフォールバックを作成するための方法を見ていきます。

フレックスボックスの歴史

すべての CSS の仕様と同じく、フレックスボックスの仕様も、現在の勧告候補になるまでに多くの変更がありました。一般的に勧告候補となった仕様には以後大幅な変更は行われませんが、フレックスボックスに関しては過去の例を見る限り例外で、何度も修正が入っています。

過去、フレックスボックスはいくつかのブラウザーで実験的に実装されました。その際にはベンダー接頭辞が使われました。このような接頭辞は、他の実装と衝突することなく、仕様の実装をブラウザーエンジニアやウェブ開発者がテストして調査するためのものであり、本番で使うためのものではありませんでした。しかし、結局は本番で使用され、実験的な仕様が変更されるたびに本番のサイトを修正しなければなりませんでした。

2009 年の仕様は、今とはだいぶ異なります。フレックスコンテナーの生成するには display: box を使い、数々の box-* プロパティがあり、今日のフレックスボックスと同じような機能を持っていました。

仕様変更によって構文が display: flexbox へと変わりました。これもベンダー接頭辞つきでした。

最終的には、フレックスコンテナーの作成には display: flex を指定するという仕様に変わりました。仕様が固まってからは、最新の仕様に対するブラウザーの対応は良好です。

古い仕様にもとづいて書かれた古い記事もまだ存在しますが、フレックスコンテナーの指定方法の違いで簡単に見分けられます。 display: boxdisplay: flexbox ならば、それは古い情報です。

ブラウザーの状況

フレックスボックスへのブラウザーの対応は良好です。現時点での大多数のブラウザーでは、ベンダー接頭辞は不要です。 Safari が 2015 年に Safari 9 で対応したことで、有名なブラウザーはすべて接頭辞不要となりました。ただし、下記の 2 つのブラウザーでは、ブラウザー間の互換性にまだ注意が必要です。

  • Internet Explorer 10。display: flexbox の仕様で実装されていて、-ms- の接頭辞が必要です。
  • UC Browser。2009 年の display: box の仕様のままで、-webkit- の接頭辞が必要です。

また、Internet Explorer 11 は最新の display: flex の仕様に対応していますが、その実装に多くのバグがあることにも注意してください。

よくある問題

フレックスボックスの問題の大部分は、開発中だった頃の仕様の変更や、実験段階の仕様を本番で使おうとすることに関連しています。IE10 や IE11 のような古いブラウザーへの後方互換性を確保したいなら、Flexbugs のサイトが役に立ちます。そこで挙げられているバグの多くが古いバージョンのブラウザーのものであり、現行のバージョンでは解決していることが分かると思います。バグにはそれぞれ回避策が示されているので、長い試行錯誤から救ってくれることでしょう。

非常に古いブラウザーにも対応したいのなら、CSS での通常の指定に加えて、ベンダー接頭辞つきの指定を使ってください。フレックスボックスへの対応が広がっている現在、接頭辞が必要な場面はどんどん少なくなっていますが。

.wrapper {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

Autoprefixer Online は、どの世代のブラウザーまで対応したいかに応じて必要な接頭辞を示してくれるので便利です。また、Can I Use では、ブラウザーで接頭辞が削除された時期を調べることができます。

有用なフォールバック方法

フレックスボックスの適用が display プロパティの値で決まるのであれば、フレックスボックスに全く対応していない古いブラウザーに対応する際には、あるレイアウト方法を別のもので上書きすることでフォールバックとすることができます。仕様は、フレックスアイテムとなるはずの要素に対して別のレイアウト方法を適用した場合に何が起こるかということも定義しています。

浮動アイテム

「float と clear はフレックスアイテムの浮動やその解除を行いません。また、フロー外へ出すこともしません」 - 3. Flex Containers

下記のライブサンプルでは、2 つのブロック要素を浮動させ、コンテナに display: flex を指定しています。これでアイテムはフレックスアイテムとなります。つまり両者は同じ高さに引き伸ばされます。float の効果は一切現れません。

フォールバックの挙動を試すには、ラッパーから display: flex を削除してください。

display: inline-block

inline-block のアイテムがフレックスアイテムになるとブロック要素になり、アイテム同士の間に空白が保持されるような display: inline-block の効果が現れなくなります。

display: flex を削除してフォールバックの挙動を確認してください。アイテム間に空白が追加されるはずです。これはインライン要素や display: inine-block を指定した要素の挙動と同じです。

display: table-

CSS のテーブル表示のプロパティは、フォールバックとしてはおそらく最も有用でしょう。なぜなら、高さを揃えるために引き伸ばすことや、縦方向の中央揃えなどのデザインパターンが可能であり、しかもそれが Internet Explorer 8 のような古いブラウザーでも動作するからです。

アイテムに display: table-cell を指定すれば、HTML のテーブルセルの性質を帯びることになります。CSS は 2 種類の無名のボックスを作ります。ひとつは <tr> の、もうひとつは <table> の役割を果たします。このおかげで、アイテムを実際の HTML 要素で包む必要はありません。これら無名ボックスは不可視でスタイルを指定することもできません。単にツリー構造を補うためのものなのです。

親要素に display: flex を指定すると、これら無名ボックスは生成されません。アイテムはフレックスコンテナの直下の子要素のままなので、フレックスアイテムになることができます。なお、テーブル関連の機能は失われます。

「注: display の値のいくつかは、元の要素の周りに無名ボックスを生成します。元の要素がフレックスアイテムの場合、まずはじめにブロック要素となるので、無名ボックスは生成されません。例えば、2 つの隣り合うフレックスアイテムに display: table-cell を指定すると、display: block を指定された 2 つの別々の フレックスアイテムとなります。1 つの無名のテーブル要素にまとめて包まれることはありません」 - 4. Flex Items

vertical-align プロパティ

下記のライブサンプルでは、display: inline-block の要素に対して vertical-align を指定しています。このプロパティは、display: table-celldisplay: inline-block のどちらにも指定できます。vertical-align による縦方向の整列は、フレックスボックスよりも先に行われます。このプロパティはフレックスボックスには無視されるので、フォールバックとして display: table-celldisplay: inline-block とともに使用できます。それによってフレックスボックスの整列系のプロパティが悪影響を受けることはありません。

機能クエリとフレックスボックス

下記のように、フレックスボックスに対応しているかどうかを機能クエリで検査できます。

@supports (display: flex) {
  // 対応しているブラウザー向けのコード
}

Internet Explorer 11 は機能クエリに対応していませんが、フレックスボックスには対応していることに注意してください。IE11 のフレックスボックスの実装にはバグが多いため、フォールバックを採用することもあるでしょう。その場合は機能クエリを使って、対応しているブラウザーだけにフレックスボックスを適用することができます。ベンダー接頭辞が必要がブラウザーをサポート対象に含めたいなら、機能クエリにもベンダー接頭辞付きの条件を追加する必要があることを忘れないでください。下記の機能クエリは UC Browser を含みます。UC Browser は機能クエリと接頭辞付きの古い構文に対応しています。

@supports (display: flex) or (display: -webkit-box) {
  // 対応しているブラウザー向けのコード
}

機能クエリについて詳しく知りたい場合は、Mozilla Hacks ブログの Using Feature Queries in CSS をご覧ください。

終わりに

このガイドで潜在的な問題やフォールバックについて学んだことで、フレックスボックスを本番で使う準備が整いました。このガイドは、問題に遭遇した場合、または古いブラウザーに対応する必要がある場合に役立ちます。