フレックスコンテナー内のアイテムの配置
===================

フレックスボックスがウェブ開発者の関心を急速に集めた理由の一つに、ウェブコンテンツで適切な配置ができる初めての機能であってことが挙げられます。正しい垂直方向の配置が可能になったことで、ついにボックスの中央寄せを簡単にできるようになりました。このガイドでは、フレックスボックスにおいて配置や行端揃えのプロパティがどのように働くかを詳しくみていきます。

ボックスを中央寄せするには、`align-items` プロパティを使って交差軸上（今回の場合は縦軸上）の配置をし、`justify-content` プロパティで主軸上（今回の場合は横軸上）の配置をします。

![内部に中央寄せされたボックスを持つコンテナー要素](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align1.png)

以下の例のコードをみてください。コンテナーや子要素のサイズを変更しても、子要素は常に中央寄せされます。

配置を制御するプロパティ
------------

本ガイドで扱うプロパティは以下のとおりです。

* `justify-content` — 全アイテムの主軸上の配置を制御します。
* `align-items` — 全アイテムの交差軸上の配置を制御します。
* `align-self` — 個別のフレックスアイテムごとに交差軸上の配置を制御します。
* `align-content` — 仕様では「フレックス行のパッキング (packing flex lines)」と説明されている。交差軸上でのフレックス行間の余白を制御します。
* `gap`, `column-gap`, `row-gap` — フレックスアイテム間にすき間または溝を生成するために使用します。

また、auto マージンがフレックスボックスでの配置にどのように使えるかについても触れます。

交差軸
---

`align-items` プロパティと `align-self` プロパティは、交差軸 (cross axis) 上のフレックスアイテムの位置を制御します。 `flex-direction` が `row` のときは列を下り、 `flex-direction` が `column` のときは行方向です。

もっとも単純なフレックスの例で、交差軸上の配置を試してみましょう。`display: flex` をコンテナーに設定すると、子要素はすべてフレックスアイテムになり、一行に配置されます。このフレックスアイテムはすべて、最も高さのあるアイテムと同じ高さになるように引き伸ばされますので、最も高さのあるアイテムが交差軸のアイテムの高さを定義することになります。フレックスコンテナーに高さが設定されている場合は、アイテム内のコンテンツの大きさにかかわらず、コンテナーの高さまでアイテムが引き伸ばされます。

![3 つのアイテムがあり、うち 1 つのアイテムには他よりも高くなる要因となる追加のテキストがある。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align2.png)

![3つのアイテムが 200 ピクセル高に引き伸ばされている](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align3.png)

アイテムが同じ高さになるのは、交差軸での配置を制御する `align-items` プロパティの初期値が `stretch` となっているためです。

アイテムの配置を制御するために、以下の値を使うことができます。

* `align-items: flex-start`
* `align-items: flex-end`
* `align-items: center`
* `align-items: stretch`
* `align-items: baseline`

以下の例では、`align-items` の値は `stretch` に設定されています。他の値についても試し、フレックスコンテナーの中でそれぞれのアイテムが互いにどのように配置されるかを確認してください。

### `align-self` で個別のアイテムを配置

`align-items` プロパティは、すべてのアイテムの `align-self` プロパティをまとめて設定します。つまり、 `align-self` プロパティでは 1 つずつ個別のアイテムを対象として指定できます。 `align-self` プロパティには、 `align-items` プロパティに使えるすべての値と、それに加えてフレックスコンテナーで定義した値にリセットするための `auto` を使うことができます。

次の例では、フレックスコンテナーには `align-items: flex-start` を設定していて、これはアイテムを交差軸上の始点に揃えます。`first-child` セレクターを使って最初のアイテムを対象として、 `align-self: stretch` を設定しており、また別のアイテムを `selected` クラスで選択して `align-self: center` を設定しています。 `align-items` の値を変更したり、個別のアイテムの `align-self` の値を変更して、どのように動作するかを試してみてください。

主軸の変更
-----

ここまでは、 `flex-direction` が `row` で、上から下へ書かれる言語の場合の動作を見てきました。これはつまり、主軸は横方向に行に沿ったものであり、一方で交差軸での配置はアイテムを上下に移動させるものとなります。

![3 つのアイテムがあり、1 つ目は flex-start、2 つ目は center、3 つ目は flex-end に配置されている。垂直軸上で配置されている。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align4.png)

`flex-direction` を `column` に変更した場合、`align-items` と `align-self` はアイテムの左右方向での配置を行うようになります。

![3 つのアイテムがあり、1 つ目は flex-start、2 つ目は center、3 つ目は flex-end に配置されている。水平軸上で配置されている。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align5.png)

次の例では `flex-direction: column` を設定し、それ以外は先の例と全く同じフレックスコンテナーを使ってこの動作を示しています。

交差軸上の配置 — align-content プロパティ
-----------------------------

ここまで、フレックスコンテナーによって定義される領域の中で、アイテム全体またはアイテム個別の配置をしてきました。折り返しのある複数行のフレックスコンテナーがある場合、 `align-content` プロパティを使えば行間でのスペース分配を制御できます。仕様では、これは「フレックス行のパッキング (packing flex lines)」として説明されています。

`align-content` が有効に動作するためには、アイテムを表示するのに必要な高さよりもフレックスコンテナーの方が高くする必要があります。このプロパティはすべてのアイテムを 1 つのセットとして扱い、余白の扱いと、セットに含まれるアイテムの配置について指示します。

`align-content` プロパティには以下の値を設定できます。

* `align-content: flex-start`
* `align-content: flex-end`
* `align-content: center`
* `align-content: space-between`
* `align-content: space-around`
* `align-content: stretch`
* `align-content: space-evenly` （フレックスボックス仕様には含まれていない）

以下の例では、フレックスコンテナーは 400 ピクセルの高さで、アイテムを表示するのに必要な高さよりも高くなっています。 `align-content` の値は `space-between` で、この場合は残る分配可能な余白 (available space) はフレックス行の*間に*分配され、フレックス行自体はコンテナーの交差軸上の始点と末尾に密着して配置されます。

`align-content` プロパティがどのように働くか、ほかの値を設定して確認してください。

列に沿った軸の時にこのプロパティの効果がどのように変わるか、 `flex-direction` を `column` に変更した場合について確認してください。変更前と同様に、すべてのアイテムを表示した上で、十分な余白が交差軸上に必要です。

**メモ:** `space-evenly` はフレックスボックス仕様書では定義されておらず、あとからボックス配置仕様書に追加されたものです。この値に対するブラウザーの対応は、フレックスボックス仕様書に定義されている他の値より遅れています。

主軸上での配置
-------

ここまで交差軸上での配置がどのように動くかを見てきましたが、ここでは主軸上での配置について見ていきます。使えるプロパティは `justify-content` の一つだけです。アイテムは主軸上ではグループとしてのみ扱われるため、プロパティも一種類となります。 `justify-content` では、アイテムを表示するのに必要な分よりも大きい空間がある場合の分配可能な余白の扱いを制御できます。

コンテナーに `display: flex` を設定した最初の例では、アイテムはコンテナーの始点に一行に整列して表示されます。これは `justify-content` の初期値が `flex-start` であるためです。すべての分配可能な余白はアイテムの後ろに置かれます。

![3 つの 100 ピクセル幅のアイテムが 500 ピクセル幅のコンテナー内にある。分配可能な余白はアイテムの後ろに置かれる。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align6.png)

`justify-content` プロパティは `align-content` と同じ値を受け付けます。

* `justify-content: flex-start`
* `justify-content: flex-end`
* `justify-content: center`
* `justify-content: space-between`
* `justify-content: space-around`
* `justify-content: space-evenly` (フレックスボックス仕様書には含まれていない)

次の例では、 `justify-content` の値は `space-between` となっています。アイテムを表示した後に余った分配可能な余白は、アイテムの間に分配されます。左右の端のアイテムはそれぞれ始点と末尾に揃えて並びます。

`flex-direction` が `column` に設定されて主軸がブロック方向となっているとき、`justify-content` はフレックスコンテナー内の分配可能なスペースがあれば、アイテム間にその方向にそってスペースを分配します。

配置と書字方向
-------

上述の配置方法において、`flex-start` と `flex-end` はいずれも書字方向に対応したものとなります。`justify-content` の値が `start` で、書字方向が英語のような左書きであれば、アイテムはコンテナーの左端から並べられます。

![3 つのアイテムが左側に並んでいる](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics5.png)

一方で書字方向がアラビア語のように右から左であれば、アイテムはコンテナーの右端から並べられます。

![3 つのアイテムは右側から並んでいる](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/basics6.png)

以下の例ではフレックスアイテムを右から左に並べるために `direction` プロパティを `rtl` を設定しています。この設定を削除したり `justify-content` の値を変更するなどして、行が右から始まる場合のフレックスボックスの動作を確認してください。

配置と flex-direction
------------------

`flex-direction` プロパティを変更した場合にも、始点は変わります。例えば `row` の代わりに `row-reverse` を設定した場合などがこれにあたります。

次の例では、`flex-direction: row-reverse` と `justify-content: flex-end` を設定してアイテムをレイアウトしています。左書きの言語では、すべてのアイテムは左側に並びます。`flex-direction: row-reverse` の値を `flex-direction: row` に変更してみてください。アイテムが右側に移動することがわかります。

こうした動作は少し紛らわしいかもしれませんが、覚えておくべき原則として、何かを変更しない限りは、文書の言語において単語が配置される方向にインライン軸、行方向の軸に沿ってフレックスアイテムが配置されます。`flex-start` は文の中でテキストが始まる側を示すことになります。

![左から始まり右で終わることを示す図。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align8.png)

`flex-direction: column` を使うことで、アイテムの配置方向を文書の言語におけるブロック方向に変更することもできます。この場合は `flex-start` は段落が始まる先頭を示すことになります。

![上から始まり下で終わることを示す図](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align10.png)

`flex-direction` を逆方向の値のいずれかに変更すると、軸の末尾側から文書の言語において単語が書かれる方向と逆方向にレイアウトされます。 `flex-start` はその軸の末尾側、つまりインライン方向では行を折り返す側、ブロック方向では最後の文が終わる側を示すことになります。

![右から始まり左で終わることを示す図](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align9.png)

![下から始まり上で終わることを示す図](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align11.png)

auto マージンを使用した主軸上での配置
---------------------

主軸上ではアイテムは一つのグループとして扱われるため、`justify-items` プロパティや `justify-self` プロパティに相当するものはありません。しかし、フレックスボックスと併せて auto マージンを使ってアイテム毎の配置をすれば、個別のアイテムまたは一部アイテムのグループを他のアイテムから分離して配置することができます。

よくあるパターンは、ナビゲーションバーでいくつかのキーアイテムが右に配置され、メイングループは左に配置されるようなものです。このようなケースは `justify-self` プロパティの使いどころだと思われるでしょうが、以下の図について考えてみましょう。3 つのアイテムが片方にあり、もう一方に 2 つのアイテムがあります。もし仮に `justify-self` をアイテム *d* に対して使うことができたとすると、意図したものであってもそうでなくても、それに続くアイテム *e* の配置も変わってしまうでしょう。

![2 つのグループに分かれた 5 つのアイテム。3 つは左側にあり、2 つは右側にある。](/ja/docs/Web/CSS/CSS_flexible_box_layout/Aligning_items_in_a_flex_container/align7.png)

4 つめのアイテムに対して `justify-content` ではなく `margin-left` に `auto` を設定すれば、先頭の 3 つから分離できます。auto マージンはマージンの方向に沿った余白をすべて占有しようとしますが、これは左右に auto マージンを設定して要素をブロック内で中央揃えするときと同じです。両側のマージンが取れるだけの余白を取ろうとするために、ブロックが中央に押し出されることになります。

以下の例では、最小限のフレックス設定をして一行に並べたフレックスアイテムと、`margin-left: auto` を設定した `push` クラスを定義しています。このクラスを削除したり他のアイテムに追加して、どのような動作をするのか確かめてください。

アイテム間にすき間を作成
------------

フレックスのアイテム間にすき間を作るには、`gap`、`column-gap`、`row-gap`の各プロパティを使用します。`column-gap` プロパティは、行内のアイテム間にすき間を作成します。`row-gap` プロパティは、`flex-wrap` が `wrap` に設定されている場合、フレックス行間にすき間を作成します。`gap` プロパティは、両方を一緒に設定する一括指定です。

関連情報
----

* ボックス配置
* フレックスボックスでのボックス配置
* グリッドレイアウトでのボックス配置