フレキシブルボックス(Flexbox)を使い柔軟なレイアウトを組む

CSS3の仕様であるフレキシブルボックスを使えば、柔軟なボックスレイアウトを組むことができます。親要素の横幅一杯に伸縮しながら複数の項目が均等配置するようにできますので、スマートフォンサイトやレスポンシブWebデザインの実装に便利な機能です。

ブロック要素を横に並べるには、float や display: table を使う方法もありますが、フレキシブルボックスではその他にも、横並びの要素の高さを自動で調整したり要素の表示順序を入れ替えたりすることができます。

フレキシブルボックスは非常に機能の多い仕様なのですが、W3Cで策定を進めている「CSS Flexible Box Layout Module Level 1」は、記事執筆時点ではまだ確定していません。
これまで何回も文法が変更になっていますので、仕様策定の動向には十分注意する必要があります。例えば、最新仕様では「display: flex」と記述しますが、旧仕様では「display: box」や「display: flexbox」と記述します。

フレキシブルボックスは便利ですが、仕様が複雑で未確定ですから、この記事では実際の案件に使えそうな一部の機能について説明します。

【コンテンツ】

  1. ブラウザの対応状況
  2. フレキシブルボックスを定義する
  3. 横方向のレイアウトを指定する
  4. flexアイテムの幅を指定し空白を埋める
  5. flexアイテムの配置方向を指定する
  6. flexアイテムの表示順序を指定する
  7. 多くのブラウザに対応する記述
  8. 仕様策定の動向

ブラウザの対応状況

デスクトップ用の主要ブラウザ最新バージョンはすべて対応しています。
ただしSafariは、ベンダープレフィックス「-webkit-」を付ける必要があります。
IE10は2012年仕様での対応、IE9以下は非対応です。

Androidブラウザでは、4.4は対応していますが、4.3以下は「-webkit-」を付け旧仕様での対応です。
iOS Safariは、iOS7では「-webkit-」を付ける必要があり、iOS6.1以下は「-webkit-」を付け旧仕様での対応です。

現状の結論としては、以下のように並列の記述をしたほうが望ましいでしょう。
(1)最新仕様の記述
(2)最新仕様にベンダープレフィックス「-webkit-」をつけた記述
(3)「display: -webkit-box」に対応する旧仕様の記述

フレキシブルボックスを定義する

【使用プロパティ】display: flex / display: inline-flex
【旧仕様の記述】display: -webkit-box / display: -webkit-inline-box
【指定先】flexコンテナ

まずフレキシブルボックスを使用する時は、親要素に「display: flex」を指定します。
これで子要素がフレキシブルボックスの影響を受けるようになります。

このときの親要素を「flexコンテナ」と呼び、子要素を「flexアイテム」と呼びます。

「display: flex」はflexコンテナをブロック要素にしますが、「display: inline-flex」を指定するとインライン要素にします。

表示は以下のようになります。
ul要素に「display: flex」を指定すると、li要素が横に並ぶようになります。

フレキシブルボックスの基本的な並び

以下はHTMLとCSSのコードです。

横方向のレイアウトを指定する

【使用プロパティ】justify-content
【旧仕様の記述】-webkit-box-pack
【指定先】flexコンテナ

flexアイテムに対して平行な軸(main axisという)に沿って、どうレイアウトするかを指定します。

justify-contentプロパティの値としては、以下の5種類があります。

説明
flex-start 左揃えでflexアイテムが配置されます。flexアイテム間にスペースはありません。これがデフォルトとなります。
flex-end 右揃えでflexアイテムが配置されます。flexアイテム間にスペースはありません。
center 中央揃えでflexアイテムが配置されます。flexアイテム間にスペースはありません。
space-between 最初のflexアイテムは左端に置かれ、最後のflexアイテムは右端に置かれます。残ったflexアイテムはその間に均等に配置されます。
space-around 左端と右端のスペースがflexアイテム間のスペースの半分になるように均等に配置されます。左端と右端をくっつけて円にしたらflexアイテム間のスペースがすべて同じになるイメージです。

これらのイメージ図は仕様書にのっていますので、以下に示します。

justify-content プロパティ イメージ図

<引用>CSS Flexible Box Layout Module Level 1

以下は、先に示した例に、「justify-content: space-between」を追加した図です。

justify-content: space-between」を追加した図

flexアイテムの幅を指定し空白を埋める

【使用プロパティ】flex
【旧仕様の記述】-webkit-box-flex
【指定先】flexアイテム

デフォルトではflexアイテムの幅はコンテンツの幅になっていますので、アイテム間に空白ができてしまいます。この空白をなくすのがflexプロパティです。

flexプロパティはショートハンドになっており、「flex-grow」「flex-shrink」「flex-basis」3つのプロパティを、その順番で同時に指定するものです。
なお3つのプロパティは、いずれかを省略することも可能です。

flex-grow

伸長係数のことです。flexアイテムの幅が他のアイテムに対してどれだけの割合で大きくなるかを決めます。相対的な数値ですから、すべてのアイテムが同じ値なら伸長率は同じになります。
デフォルトは "0" です。"0" では伸長しませんからコンテンツ幅となります。

flex-shrink

縮小係数のことです。flexコンテナの幅が狭くflexアイテムの幅をとることができないと、マイナスのスペース値を与えflexアイテムの幅を縮小しなければなりませんが、その際に効いてきます。flex-growと同じく他のアイテムに対しての相対値になります。
デフォルトは "1" です。"0" にすると縮小しませんから、Window幅を縮めたときflexアイテムはflexコンテナからはみ出してしまいます。

flex-basis

flex-growとflex-shrinkが効く前のイニシャルのflexアイテムの幅を設定します。
デフォルトは "auto" です。その他数値で指定します。数値単位はpx,em,%などが使え、%での指定はflexコンテナ幅に対する割合を示します。
"auto" を指定すると、コンテンツ内容による幅にflexアイテムそれぞれが設定されます。

flexプロパティを設定するときの注意としては、flex-grow/flex-shrink/flex-basis の省略時の値です。flex-grow/flex-basisはデフォルト値と異なりますので注意します。

<省略時の値>
flex-grow ⇒ 1
flex-shrink ⇒ 1
flex-basis ⇒ 0%

例えば、「flex: 1;」と設定したときは、flex-shrinkとflex-basisが省略されたことになりますから、「flex: 1 1 0%;」と同じ意味になります。

コンテンツに応じた幅とし空白を埋める設定

li要素に、「flex: 1 1 auto;」あるいは省略記述で「flex: auto;」と指定します。

表示は以下のようになります。

コンテンツに応じた幅とし空白を埋める設定をした表示例

同一幅とし空白を埋める設定

li要素に、「flex: 1 1 [数値];」あるいは省略記述で「flex: 1;」と指定します。

表示は以下のようになります。

同一幅とし空白を埋める設定をした表示例

【注意!】
旧仕様のbox-flexは意味合いが少し異なります。ショートハンドとはならず、値に1つの数値しか指定できません。
デフォルトは"0.0"であり、指定する場合も「-webkit-box-flex: 1;」のように記述します。

flexアイテムの配置方向を指定する

【使用プロパティ】flex-direction
【旧仕様の記述】-webkit-box-orient & -webkit-box-direction
【指定先】flexコンテナ

flexアイテムは横方向だけでなく、縦方法にも配置できます。
また配置順序を逆にすることもできます。

flex-directionプロパティの値としては、以下の4種類があります。

説明
row 横方向にflexアイテムが順番に配置されます。これがデフォルトとなります。
row-reverse 横方向にflexアイテムが逆の順番に配置されます。
column 縦方向にflexアイテムが順番に配置されます。
column-reverse 縦方向にflexアイテムが逆の順番に配置されます。

【注意!】
IE10/IE11では高さの計算にバグがあり、「flex-direction: column」は正しく動作しません。

flexアイテムの表示順序を指定する

【使用プロパティ】order
【旧仕様の記述】box-ordinal-group ※使用法は異なる
【指定先】flexアイテム

flexアイテムの表示順序を細かく指定できます。

例えば、以下のように指定したとします。

このときの表示は以下になります。

flexアイテムの表示順番を入れ替えた例

注意点としては、orderプロパティは表示の順番を変えるだけということです。
上記の例でもlast-childである「お問い合わせ」だけに右ボーダーはないのですが、それが適用されています。

orderプロパティのデフォルト値は "0" ですので、"-1" をどれか1つに指定すると、そのアイテムが先頭になります。"1" をどれか1つに指定すると、そのアイテムが最後になります。

多くのブラウザに対応する記述

ここまでのコード例は、最新仕様に対するものだけしか示していませんでした。
それをSafariや古いブラウザにも対応させてみます。

例としては、以下のようにflexアイテムが横方向にコンテンツに応じた幅で順番に並んだレイアウトとします。

コンテンツに応じた幅とし空白を埋める設定をした表示例

HTMLは以下になります。

CSSは以下になります。

仕様策定の動向

「CSS Flexible Box Layout Module Level 1」については、
記事執筆時点での最新仕様は、2014年3月25日発行の最終作業草案「W3C Last Call Working Draft」です。
またその後も何回かEditor's Draftが出ており、Editor's Draft最新版は2014年8月19日発行のものです。

スポンサーリンク

ページの先頭へ