フレックスボックスの典型的な用途
================

このガイドでは、フレックスボックスの一般的な使用用途（フレックスボックスが他のレイアウト方法よりも有意義である場合）について見ていきます。

なぜフレックスボックスを選ぶのか？
-----------------

ブラウザーが完全対応しているならば、アイテムの集まりをある方向へ並べる用途にはフレックスボックスが適しています。アイテムを並べる際には、コンテナーの内部でのアイテムの寸法や、アイテム同士の余白を調節したくなると思います。フレックスボックスはそのような用途のために設計されています。フレックスボックスと CSS グリッドレイアウトとの違いについては フレックスボックスと他のレイアウト方法の関係 をご覧ください。そこでは、フレックスボックスが CSS レイアウトの全体像にどのように適合しているのかを説明しています。

現状では、グリッドレイアウトのほうが適しているけれどもそれを使えない、という場面でもフレックスボックスはよく使われます。また、アイテムを整列する手段としても使われます。これは、ボックス配置がブロック要素のレイアウト方法として実装されれば解決するでしょう。このガイドでは、現状での典型的なフレックスボックスの使用例を紹介します。

ナビゲーション
-------

ナビゲーションのよくあるパターンとして、水平な棒状にリストを表示するというものがあります。このパターンは見た目とは裏腹に、フレックスボックスの登場以前は実現が難しいものでした。フレックスボックスならばとても簡単であり、うってつけの出番だと言えます。

水平方向に表示したいアイテム群がある場合、空間が残ることがあります。この空間をどうするかを決めなければなりませんが、いくつかの選択肢があります。アイテムの外側に空間を表示して、アイテムの間や周囲に余白を設けるか、アイテムの内側に空間を吸収して、アイテムを伸長してこの空間を占めるようにするか、どちらかにする必要があります。

### アイテムの周囲に余白を分配

アイテムの間または周囲に余白を分配するには、フレックスボックスの配置プロパティと `justify-content` プロパティを使います。このプロパティの詳細については、フレックスコンテナー内のアイテムの配置をご覧ください。そこでは、主軸におけるアイテムの配置について説明しています。

下記のライブ例では、アイテムをそれぞれ本来の大きさで表示しています。また、 `justify-content: space-between` によって、アイテム同士の間に同じ幅の余白を配置しています。値に `space-around` や、ブラウザーが対応している場合は `space-evenly` を指定することで、余白の配置方法を変えることができます。 `flex-start` で余白をアイテム群の後ろに配置したり、 `flex-end` で余白をアイテム群の前に配置したり、 `center` でアイテム群をナビゲーションの中央に配置したりすることもできます。

### アイテムの内側に余白を分配

ナビゲーションでのもう一つのパターンは、余白をアイテムの間ではなく、アイテム自身の内部に配置することです。この場合は、 `flex` プロパティを使うことで、アイテムを互いの比率を保ったまま伸縮することができます。主軸方向のフレックスアイテムの比率の制御に書かれている通りです。

もしナビゲーションアイテムの size プロパティを尊重しつつ、利用できる空間を均等に共有したいのであれば、 `flex: auto` を使用することができます。これは `flex: 1 1 auto` の一括指定で、すべてのアイテムは flex-basis が auto の状態から伸縮します。これは、より大きなアイテムは、利用できる空間の大きさの割り当てが他と同じだけであったとしても、より大きなサイズから始めるので、より大きな空間を占めることということです。

下記のライブサンプルの `flex: auto` を `flex: 1` に変えてみてください。これは `flex: 1 1 0` の短縮版で、すべてのアイテムの幅が同じになります。なぜなら、 flex-basis が 0 となって空間が均等に分配されるからです。

ナビゲーションの分割
----------

主軸（横軸）でアイテムを整列するもうひとつの方法は、マージンを auto にすることです。これにより、一方のアイテム群を左揃えにして別のアイテム群を右揃えにする、というナビゲーションバーのデザインパターンが可能になります。下記の例では、 auto マージンを使用した主軸上での配置に書かれている、マージンを auto にする技法を使っています。

アイテムは、フレックスボックスの初期動作である `flex-start` で主軸に配置されています。 `gap` プロパティを使用してアイテム間にすき間を作成しています。そして、左マージンを auto にすることで、最後のアイテムを右に配置しています。このクラスをあるアイテムから別のアイテムに移動させることで、分割される位置を変更することができます。

アイテムの中央揃え
---------

フレックスボックスの登場以前、開発者たちは「ウェブデザインで最も難しいのは垂直方向の中央揃えだ」と冗談を言っていました。下記のライブ例のとおり、フレックスボックスの配置プロパティを使用することで、簡単に解決できるようになりました。

配置では、 `flex-start` でアイテムを先頭に、 `flex-end` で末尾に配置することができます。

将来、ボックス配置の各プロパティがブロック要素のレイアウト方法として完全に実装されれば、単一のアイテムの中央揃えのためにフレックスコンテナーを作る必要はなくなります。しかし現状では、1 つのものを別のものの中で正確に中央に配置したければ、フレックスボックスを使うことになります。上記の例のように、コンテナーをフレックスコンテナーとして扱ってフレックスコンテナーに `align-items` を指定するか、フレックスアイテム自身に `align-self` を指定してください。

フッターが下端に張り付くカード
---------------

フレックスボックスや CSS グリッドを使ってコンテナー内のカード状の部品を並べて配置する場合、それらの制御はコンテナーの直下の要素であるカード自身にしか及びません。どういうことかと言うと、各カードの中身の量が異なる場合、カードはグリッド領域やフレックスコンテナーの高さに引き伸ばされます。そして、カードの内部では通常のブロックレイアウトが用いられます。つまり、中身の量が少ないカードでは、カードのフッターはカードの下端に張り付くのではなく、フッターが下端から浮き上がってしまいます。

![2 枚のカード部品は、部品の内部がラッパーと一緒に伸びることはない。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Typical_use_cases_of_flexbox/flex-cards.png)

フレックスボックスはこれを解決できます。カード自身もフレックスコンテナーにして、 `flex-direction``: column` を指定します。そしてカードの本文領域に `flex: 1` を指定します。これは `flex: 1 1 0` の一括指定です。アイテムは `0` の flex-basis をもとに伸縮します。引き伸ばせるフレックスアイテムが本文領域だけの場合、本文領域はフレックスコンテナー内の空間をすべて取り込み、フッターを下端に張り付かせます。ライブサンプルから `flex` プロパティを削除すると、フッターが本文の真下に移動するのを確認できます。

メディアオブジェクト
----------

メディアオブジェクトは、ウェブデザインでよく見られるパターンです。このパターンでは、画像やその他の要素が片側に、テキストが右側に配置されています。メディアオブジェクトは、反転させることができるのが理想です。すなわち、画像を左から右に移動することです。

このパターンは、コメント欄をはじめ、画像や説明を表示する必要がある場所でよく見られます。フレックスボックスを使用すると、画像を含むメディアオブジェクトの部分が画像から大きさを取得し、メディアオブジェクトの本文が残りの空間を確保するように拡大縮小します。

下のライブ例では、メディアオブジェクトが表示されています。配置プロパティを使用して、横軸のアイテムを `flex-start` に揃え、`.content` のフレックスアイテムを `flex: 1` に設定しています。前述のカラムレイアウトカードのパターンと同様に、`flex: 1` を使用することで、カードのこの部分を伸長させることができます。

このライブ例では、デザインの中でメディアオブジェクトを制約するさまざまな方法を試してみることができます。

画像が大きくなりすぎるのを防ぐには、 `max-width` を画像に指定します。画像領域のフレックスボックスの指定は初期値のままなので、縮むことはできますが伸びることはできません。また、初期値では `flex-basis` は auto なので、画像の `width` や max-width が `flex-basis` となります。


```css
.image img {
  max-width: 100px;
}
```


両方の領域の比率を維持したまま伸縮させることもできます。両者に `flex: 1` を指定すると、0 の `flex-basis` をもとに伸縮することになります。つまり両者の幅は同じになります。内容物を元に、両方とも `flex: auto` に設定すると、内容物の寸法や、画像の幅などフレックスアイテムに直接適用される大きさに合わせて拡大縮小することができます。


```css
.media .content {
  flex: 1;
  padding: 10px;
}

.image {
  flex: 1;
}
```


両者に別々の `flex-grow` の比率を指定することもできます。例えば画像領域には `flex: 1`、文章領域には `flex: 3` というように。これは、両者に `0` の `flex-basis` が適用されますが、指定された `flex-grow` に従って別々の比率で領域が確保されることを意味します。このように使用される flex プロパティについては、主軸方向のフレックスアイテムの比率の制御で詳しく説明されています。


```css
.media .content {
  flex: 3;
  padding: 10px;
}

.image {
  flex: 1;
}
```

### メディアオブジェクトを反転させる

画像が右で文章が左になるようにメディアオブジェクトの表示を切り替えるには、`flex-direction` プロパティに `row-reverse` を指定します。下記のライブサンプルでは、`flipped` のクラスを `.media` の隣に追加することで実現しています。 HTML からそのクラスを削除すれば、どのように表示が変わるのかが分かるでしょう。

フォームコントロール
----------

フレックスボックスはフォームコントロールのスタイル指定に関しては特に便利です。フォームにはたくさんのマークアップや小さな要素があり、それらを配置したいと考えるはずです。よくあるパターンは `<input>` 要素と `<button>` の組み合わせでしょう。検索フォームや、単に訪問者にメールアドレスを入力してもらう用途などで使われます。

フレックスボックスならばこのようなレイアウトを簡単に実現できます。下記の例では、`<button>` と `<input>` フィールドを枠線と `display: flex` を指定したラッパーの中に入れています。`<input>` フィールドを引き伸ばすために flex プロパティを使っています。ただし、ボタンは引き伸ばされません。つまり、確保できる領域の変化に応じて伸縮する入力欄を備えたフォーム部品を実現できます。

ボタンを右側に置いたのと同じように、ラベルやアイコンを左側に置くことも簡単にできます。今回はラベルを置きました。背景色以外は、何もレイアウトを変更していません。伸縮する入力欄は少し狭くなるものの、2 つのアイテムが取った残りの領域をすべて使うことになります。

このようなパターンのおかげで、デザインに合わせたフォーム要素のライブラリーを簡単に作れます。要素の追加にも簡単に対応できます。伸縮するアイテムとしないアイテムを組み合わせる用途では、フレックスボックスの柔軟性の恩恵を存分に受けることができるのです。

終わりに
----

上に挙げたパターンを見て回るうちに、フレックスボックスの最適な利用場面を考え始めたことと思います。いろいろな選択肢があることでしょう。伸縮するアイテムとしないアイテムを組み合わせたり、フレックスアイテムの中身のサイズをフレックスアイテム自身に反映させたり、比率に沿ってフレックスボックスの領域を分け合ったり。すべてはあなた次第です。

コンテンツの最適な表現方法を思い描いてみてください。そしてその実現にあたって、フレックスボックスや他のレイアウト方法をどのように利用できるのかを調べてみてください。