ボックス要素の横並びをCSSで行う場合、これまではfloat
プロパティを使うのが主流でした。しかし、CSS3の新機能「Flexbox」を使うとfloat
よりも簡潔なコードで、ボックスの豊富なレイアウトが可能です。本記事ではWebページの作成を通してFlexboxの特徴と使い方について解説します。
Flexboxはボックスレイアウト用のCSS3
Flexboxとは、ボックスのレイアウト方法を定めるCSS3の機能です。ボックスとは、HTML上の各要素が生成する領域のことです。下図のHTMLコードのWebページでは、div
要素・h1
要素・p
要素がそれぞれボックスを生成します。
Flexboxでは、ボックスを横並びにしたり、右寄せ・中央寄せ・左寄せをしたりと、さまざまなレイアウトを少量のコードで実現できます。
大手のプロダクトで使われるFlexbox
Flexboxは、既に大手のプロダクトで使われ始めています。Twitter社製のUIフレームワーク「Bootstrap 4」では、グリッドレイアウト・カードデザインのレイアウト等の一部のUIで採用されています。Drifty Co社のハイブリッドアプリ(Web技術を使って開発するアプリ)作成フレームワーク「Ionic 2」では、グリッドレイアウト、ボタン、ナビゲーションなど、多くのボックスレイアウトに用いられています。
GoogleのショーケースChrome Experimentsに掲載された、弊社開発の「Particle Develop」でもグリッドレイアウトやタブ、ボタン等にFlexboxを採用しました。
今回作成するWebページについて
今回はレスポンシブなページのコーディングを例にしてFlexboxの説明します。まずは完成形のページをご覧ください。シンプルなカラムレイアウトをFlexboxを使って実現しています。
Flexboxでのレイアウト方法
まずはヘッダー部分のコーディングです。
HTMLコードは次のとおりです。
<header> <img src="images/logo.png" alt=""> <ul> <li><a href="">menu1</a></li> <li><a href="">menu2</a></li> <li><a href="">menu3</a></li> </ul> </header>
ヘッダー部分のコーディングには、次の3つの過程が必要です。
- ボックスをFlexboxレイアウトとして指定する
- ロゴとメニューを左右に振り分ける
- ヘッダー内を縦方向中央揃えにする
Flexboxレイアウトの指定と2つの軸
ボックスの横並びや縦並びといったFlexboxのレイアウトを指定するとき、ボックスの親要素のスタイルのdisplay
プロパティにflex
を設定します。今回は、header
タグとul
タグです。
header { display: flex; } ul { display: flex; }
Flexboxにおけるボックスのレイアウトは、「主軸」と「交差軸」という2つの軸によって決定されます。初期状態では、左から右方向の軸が主軸、上から下方向の軸が交差軸となります。
横方向・縦方向にボックスを並べる
主軸に沿った方向(初期状態で横方向)の並び方はjustify-content
プロパティで設定します。各々の設定値は次の通りです。
flex-start
→ 始端揃え(左揃え、初期値)center
→ 中央揃えflex-end
→ 終端揃え(右揃え)space-between
→ 均等配置(両端ボックスは始端と終端)space-around
→ 均等配置(両端ボックスは始端、終端からボックス間隔の半分の距離)
交差軸に沿った方向(初期状態で縦方向)の並び方はalign-items
プロパティで設定します。各々の設定値は次の通りです。
stretch
→ 親要素と同じ高さに伸びる(初期値)flex-start
→ 始端揃え(上揃え)center
→ 中央揃えflex-end
→ 終端揃え(下揃え)
ヘッダー部分では、ロゴとメニューを左右に振り分け、メニューを上下中央揃えにするので、次のようにCSSを設定します。
header { justify-content: space-between; /* 左右均等分布 */ } ul { align-items: center; /* 上下中央揃え */ }
ボックスを複数行に並べる
つづいて、3カラムのカード部分のレイアウトです。HTMLコードを抜粋したものが下記です。main
タグの中にdiv
タグが8個あります。
<main> <div class="animal"> <h1>うさぎ</h1> <img src="images/animal1.jpg" alt=""> <p>全身が柔らかい体毛で覆われている小型獣である。最大種はヤブノウサギで体長 50–76 cm。</p> </div> <div class="animal"> <h1>キツネ</h1> <img src="images/animal2.jpg" alt=""> <p>食性は肉食に近い雑食性。鳥、ウサギ、齧歯類などの小動物や昆虫を食べる。</p> </div> (中略) </main>
div
要素のボックス要素を親要素の1/3
の幅にし、横並びにしたいので次のようにスタイルを設定するとよさそうです。
main { display: flex; } main div.animal { width: calc(33.3% - 10px); margin: 5px; }
ところが、このコードを実行するとボックスは3カラムにならず、一行に並びます。Flexboxの初期設定では、ボックスは親要素の幅にかかわらず一行に並ぶためです。
複数行のレイアウトを行うには、flex-wrap
プロパティにwrap
を設定します。
nowrap
→ ボックスを単一行に配置するwrap
→ ボックスを複数行に配置する
今回の例では次のように指定します。
main { flex-wrap: wrap; }
これで3カラムのカードレイアウトが完成しました。
また、嬉しいことに各カードの高さが揃っています。float
を使ったレイアウトでは、高さ揃えは複数のスタイルを指定したり、JavaScriptを使ったりと煩雑でしたが、Flexboxの場合はプロパティ一つで可能(※)です。
※ align-items
プロパティの初期値がstretch
によるものです。複数行レイアウトの場合、align-items:stretch;
が指定されたボックスの高さは、行の高さの最大値まで広がるため、各行毎に高さが揃います。
ここまでのCSSコードとデモは下記です。
次のページでは、Flexboxにおけるレスポンシブ対応について解説します。