FlexboxでAndroid 4未対応のボックス折り返し(flex-wrap)を実現する方法


CSS3のFlexboxを試した人からよく聞くのが「Android 4系でボックスの折り返しができない」という声です。本記事ではポリフィルを使ってAndroid 4でもflex-wrapによるボックスの折り返しを実現する方法を紹介します

なお、Flexboxの基本については記事「初心者でも始められるFlexbox入門 - ICS MEDIA」を参照ください。

Android 4におけるflex-wrapの挙動

Android 4におけるボックスの折り返しができないとはどういうことなのか、まずその挙動を確認してみましょう。

flex-wrapプロパティにwrap値を指定すると、親要素の横幅を超えたときにボックスが折り返し、複数行のレイアウトが可能になります。

下記のようなHTML・CSSコードを例にして考えてみます。リストで並べたボックスに対して、Flexboxレイアウトと折り返しを指定しています。

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>
ul {
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
}

ulタグにはflex-wrap: wrap;が設定されていますが、Android 4ではflex-wrapプロパティが無効なため、折り返しできません

ポリフィルを使ってAndroid 4のflex-wrapを擬似的に再現

Android 4でflex-wrapによる折り返しを実現する方法の1つは、ポリフィル「flexibility」を使うことです。使い方は下記です。

① ポリフィルを読み込む

flexibilityのスクリプトを読み込みます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/flexibility/2.0.1/flexibility.js"></script>

② 要素のdata-style属性に、Flexboxレイアウト用のスタイルを記述する

Flexbox対応ブラウザ向けに記述していたスタイルを、Flexboxレイアウトを適用したい要素のdata-style属性にて記述します。flex-wrapを指定する場合はwidthも指定しないと意図したレイアウトにならないのでご注意ください

<ul data-style="width:100%; display:flex; flex-wrap:wrap;">

また、CSS、data-styleと、スタイル定義が2箇所になってしまうので、修正する際は必ず両方修正するようにしましょう。

flexibility()メソッドを使ってポリフィルを適用する

flexibilityには、Flexboxに対応していないブラウザ向けにFlexboxレイアウトを強制的に適用するflexibility()メソッドがあります。Android 4系ブラウザのみに適用するよう、下記のJavaScriptを記述します。

document.addEventListener("DOMContentLoaded", function () {
  var ua = navigator.userAgent;
  if (ua.indexOf("Android 4.") > 0) {
    flexibility(document.body);
  }
});

厳密にはflex-wrapが動作しないのは4.3以下ですが、4.4系の一部(Galaxy等)でflex-wrapが動作しない例もありますので、4系全般に対応するのが望ましいでしょう。

全コードは下記です。

以上で、Android 4でも折り返しが有効になりました。

Android 4でも安心してFlexboxを使おう

Android 4系のユーザーは今後減ってくるとは言え、まだ一定数のユーザーが存在し(参考記事「Android Developers 」)、対応を余儀なくされる場合もあるでしょう。そのような状況でFlexboxのflex-wrapでの折り返しを行いたい場合に、この方法を試してみてください。