このガイドでは、フレックスボックスの一般的な使用例を紹介します。 — 他のレイアウト方法よりも適した使い方です。
なぜフレックスボックスを選ぶのか?
ブラウザーが完全対応しているならば、アイテムの集まりをある方向へ並べる用途にはフレックスボックスが適しています。アイテムを並べる際には、コンテナの内部でのアイテムの寸法や、アイテム同士の余白を調節したくなると思います。フレックスボックスはそのような用途のために設計されています。フレックスボックスと CSS グリッドレイアウトとの違いについては フレックスボックスと他のレイアウト方法の関係 をご覧ください。そこでは、フレックスボックスが CSS レイアウトの全体像にどのように適合しているのかを説明しています。
現状では、グリッドレイアウトのほうが適しているけれどもそれを使えない、という場面でもフレックスボックスはよく使われます。また、アイテムを整列する手段としても使われます。これは、Box Alignment がブロック要素のレイアウト方法として実装されれば解決するでしょう。このガイドでは、現状での典型的なフレックスボックスの使用例を紹介します。
ナビゲーション
ナビゲーションのよくあるパターンとして、水平な棒状にリストを表示するというものがあります。このパターンは見た目とは裏腹に、フレックスボックスの登場以前は実現が難しいものでした。フレックスボックスならばとても簡単であり、うってつけの出番だと言えます。
アイテムを水平に表示する際に、空白が必要になる場合があります。その空白をどうするか。2 つの選択肢があります。アイテムの外側に置く場合は、アイテム同士の間やアイテムの周囲に空白を配置することになります。アイテムの内側に入れる場合は、アイテムが空白を受け入れてサイズが広がるようにする方法が必要です。
空白を外側に配置
アイテム間や周囲に空白を置くには、フレックスボックスの整列系のプロパティと justify-content
プロパティを使います。このプロパティの詳細については フレックスコンテナにおけるアイテムの位置合わせ をご覧ください。そこでは、主軸 (横軸) でのアイテムの整列について説明しています。
下記のライブサンプルでは、アイテムをそれぞれ本来のサイズで表示しています。また、justify-content: space-between
によって、同じ幅の空白をアイテム同士の間に配置しています。値に space-around
や、ブラウザーが対応している場合は space-evenly
を指定することで、空白の配置方法を変えることができます。flex-start
で空白をアイテム群の後ろに配置し、flex-end
で空白をアイテム群の前に配置し、center
でアイテム群をナビゲーションの中央に配置することもできます。
空白を内側に配置
ナビゲーションでの別のパターンは、空白をアイテム同士の間ではなく、アイテム自身の内部に配置することです。この場合は、Flex アイテムを主軸に沿わせる時の制御割合 に書かれているように、flex
プロパティを使うことで、アイテムを互いの比率を保ったまま伸縮できます。
ナビゲーションのアイテムの幅を同じにしたいなら、flex: auto
を指定します。これは flex: 1 1 auto
の短縮版です。すべてのアイテムは自動の flex-basis をもとに伸縮します。つまり、他よりも中身が多いアイテムは、占める領域も他より多くなります。
下記のライブサンプルの flex: auto
を flex: 1
に変えてみてください。これは flex: 1 1 0
の短縮版で、すべてのアイテムの幅が同じになります。なぜなら、flex-basis が 0 となって領域が均等に配分されるからです。
ナビゲーションの分割
主軸 (横軸) でアイテムを整列するもうひとつの方法は、自動マージンを使うことです。これにより、一方のアイテム群を左揃えにして別のアイテム群を右揃えにする、というナビゲーションバーのデザインパターンが可能になります。
下記の例では、主軸上での位置合わせに auto マージンを使う に書かれている自動マージンの技法を使っています。アイテムは flex-start
によって主軸上に揃えられます。これはフレックスボックスの既定の挙動です。そして、左マージンに auto を指定することで、そのアイテムだけは右に揃えられます。分割される地点を変えるには、CSSクラス "push-right" を別のアイテムに移してください。
下記の例では、フレックスアイテムにマージンを指定して、アイテム間の空白を作っています。また、フレックスコンテナにネガティブマージンを指定して、コンテナの幅いっぱいにアイテムを表示するようにしています。Box Alignment の仕様にある gap
プロパティがフレックスボックスに実装されるまでは、このようにマージンを使う必要があります。
アイテムの中央揃え
フレックスボックスの登場以前、開発者たちは「Webデザインで最も難しいのは垂直方向の中央揃えだ」と冗談を言っていました。今では、下記のライブサンプルのとおり、フレックスボックスの整列系のプロパティで簡単にできます。
下記のコード内の center
の代わりに、先頭に揃える flex-start
や末尾に揃える flex-end
を指定して、整列の挙動を試してみてください。
将来、Box Alignment の各プロパティがブロック要素のレイアウト方法として完全に実装されれば、単一のアイテムの中央揃えのためにフレックスコンテナを作る必要はなくなります。しかし現状では、1 つのものを別のものの中で正確に中央に配置したければ、フレックスボックスを使うことになります。上記の例のように、コンテナをフレックスコンテナとして扱ってフレックスコンテナに align-items
を指定するか、フレックスアイテム自身に align-self
を指定してください。
フッターが下端に張り付くカード
フレックスボックスや CSS グリッドを使ってコンテナ内のカード状の部品を並べて配置する場合、それらの制御はコンテナの直下の要素であるカード自身にしか及びません。どういうことかと言うと、各カードの中身の量が異なる場合、カードはグリッドエリアやフレックスコンテナの高さに引き伸ばされます。そして、カードの内部では通常のブロックレイアウトが用いられます。つまり、中身の量が少ないカードでは、カードのフッターはカードの下端に張り付くのではなく、フッターが下端から浮き上がってしまいます。
フレックスボックスはこれを解決できます。カード自身もフレックスコンテナにして、flex-direction
: column
を指定します。そしてカードの本文エリアに flex: 1
を指定します。これは flex: 1 1 0
の短縮版です。アイテムは 0
の flex-basis をもとに伸縮します。引き伸ばせるフレックスアイテムが本文エリアだけの場合、本文エリアはフレックスコンテナ内の空白をすべて取り込み、フッターを下端に張り付かせます。ライブサンプルから flex
プロパティを削除すると、フッターが本文の真下に移動するのを確認できます。
メディアオブジェクト
メディアオブジェクトはWebデザインの一般的なパターンです。このパターンは画像などを左側に持ち、文章をもう右側に持ちます。理想的には、メディアオブジェクトを反転させて画像を左から右へ移すことができるようにすべきでしょう。
このようなパターンはどこでも見かけます。コメント欄や、画像とその説明を表示する場合などです。フレックスボックスならば、メディアオブジェクトの画像エリアには画像の寸法そのままの領域を確保させて、余った領域はすべて文章エリアに使わせるという柔軟な指定ができます。
下記のライブサンプルはメディアオブジェクトの例です。整列系のプロパティを使ってアイテムを交差軸 (縦軸) の flex-start
に揃えて、.content
を指定したフレックスアイテムに flex: 1
を指定しています。先述のカード内の縦方向の配置と同じく、flex: 1
はその要素を引き伸ばせることを意味します。
下記のような、メディアオブジェクトの実用でよくある場面を、上記のライブサンプルで試してみたくなりませんか?
画像が大きくなりすぎるのを防ぐには、max-width
を画像に指定します。画像エリアのフレックスボックスの指定は初期値のままなので、縮むことはできますが伸びることはできません。また、初期値では flex-basis
は auto なので、画像の width
や max-width が flex-basis
となります。
.image img {
max-width: 100px;
}
両方のエリアの比率を維持したまま伸縮させることもできます。両者に flex: 1
を指定すると、0 の flex-basis
をもとに伸縮することになります。つまり両者の幅は同じになります。両者の比率を中身の量で決めるために flex: auto
を指定することもできます。その場合は、中身のサイズに応じて、または画像の width ようにフレックスアイテムに直接適用されるサイズに応じて伸縮します。
.media .content {
flex: 1;
padding: 10px;
}
.image {
flex: 1;
}
両者に別々の flex-grow
の比率を指定することもできます。例えば画像エリアには flex: 1
、文章エリアには flex: 3
というように。これは、両者に 0
の flex-basis
が適用されますが、指定された flex-grow
に従って別々の比率で領域が確保されることを意味します。このように使用される flex プロパティについては、Flex アイテムを主軸に沿わせる時の制御割合 で詳しく説明されています。
.media .content {
flex: 3;
padding: 10px;
}
.image {
flex: 1;
}
メディアオブジェクトを反転させる
画像が右で文章が左になるようにメディアオブジェクトの表示を切り替えるには、flex-direction
プロパティに row-reverse
を指定します。下記のライブサンプルでは、.flipped
のクラスを .media
の隣に追加することで実現しています。HTML からそのクラスを削除すれば、どのように表示が変わるのかが分かるでしょう。
フォームコントロール
フレックスボックスはフォームコントロールのスタイル指定に関しては特に便利です。フォームにはマークアップと小さな要素がたくさんあり、それらを整列させたいと考えるはずです。よくあるパターンは <input>
要素と <button>
の組み合わせでしょう。検索フォームや、単に訪問者にメールアドレスを入力してもらう用途などで使われます。
フレックスボックスならばこのようなレイアウトを簡単に実現できます。下記の例では、枠線と display: flex
を指定したラッパーの中に <button>
と <input>
フィールドを入れています。<input>
フィールドを引き伸ばすために flex プロパティを使っています。ただし、ボタンは引き伸ばされません。つまり、確保できる領域の変化に応じて伸縮する入力欄を備えたフォーム部品を実現できます。
ボタンを右側に置いたのと同じように、ラベルやアイコンを左側に置くことも簡単にできます。今回はラベルを置きました。背景色以外は、何もレイアウトを変更していません。伸縮する入力欄は少し狭くなるものの、2 つのアイテムが取った残りの領域をすべて使うことになります。
このようなパターンのおかげで、デザインに合わせたフォーム要素のライブラリを簡単に作れます。要素の追加にも簡単に対応できます。伸縮するアイテムとしないアイテムを組み合わせる用途では、フレックスボックスの柔軟性の恩恵を存分に受けることができるのです。
終わりに
上に挙げたパターンを見て回るうちに、フレックスボックスの最適な利用場面を考え始めたことと思います。いろいろな選択肢があることでしょう。伸縮するアイテムとしないアイテムを組み合わせたり、フレックスアイテムの中身のサイズをフレックスアイテム自身に反映させたり、比率に沿ってフレックスボックスの領域を分け合ったり。すべてはあなた次第です。
コンテンツの最適な表現方法を思い描いてみてください。そしてその実現にあたって、フレックスボックスや他のレイアウト方法をどのように利用できるのかを調べてみてください。