フレックスコンテナー内のアイテムの配置
フレックスボックスがウェブ開発者の関心を急速に集めた理由の一つに、ウェブコンテンツで適切な配置ができる初めての機能であってことが挙げられます。正しい垂直方向の配置が可能になったことで、ついにボックスの中央寄せを簡単にできるようになりました。このガイドでは、フレックスボックスにおいて配置や行端揃えのプロパティがどのように働くかを詳しくみていきます。
ボックスを中央寄せするには、align-items
プロパティを使って交差軸上(今回の場合は縦軸上)の配置をし、justify-content
プロパティで主軸上(今回の場合は横軸上)の配置をします。
以下の例のコードをみてください。コンテナーや子要素のサイズを変更しても、子要素は常に中央寄せされます。
配置を制御するプロパティ
本ガイドで扱うプロパティは以下のとおりです。
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
をコンテナーに設定すると、子要素はすべてフレックスアイテムになり、一行に配置されます。このフレックスアイテムはすべて、最も高さのあるアイテムと同じ高さになるように引き伸ばされますので、最も高さのあるアイテムが交差軸のアイテムの高さを定義することになります。フレックスコンテナーに高さが設定されている場合は、アイテム内のコンテンツの大きさにかかわらず、コンテナーの高さまでアイテムが引き伸ばされます。
アイテムが同じ高さになるのは、交差軸での配置を制御する 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
で、上から下へ書かれる言語の場合の動作を見てきました。これはつまり、主軸は横方向に行に沿ったものであり、一方で交差軸での配置はアイテムを上下に移動させるものとなります。
flex-direction
を column
に変更した場合、align-items
と align-self
はアイテムの左右方向での配置を行うようになります。
次の例では 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
であるためです。すべての分配可能な余白はアイテムの後ろに置かれます。
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
で、書字方向が英語のような左書きであれば、アイテムはコンテナーの左端から並べられます。
一方で書字方向がアラビア語のように右から左であれば、アイテムはコンテナーの右端から並べられます。
以下の例ではフレックスアイテムを右から左に並べるために 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
は文の中でテキストが始まる側を示すことになります。
flex-direction: column
を使うことで、アイテムの配置方向を文書の言語におけるブロック方向に変更することもできます。この場合は flex-start
は段落が始まる先頭を示すことになります。
flex-direction
を逆方向の値のいずれかに変更すると、軸の末尾側から文書の言語において単語が書かれる方向と逆方向にレイアウトされます。 flex-start
はその軸の末尾側、つまりインライン方向では行を折り返す側、ブロック方向では最後の文が終わる側を示すことになります。
auto マージンを使用した主軸上での配置
主軸上ではアイテムは一つのグループとして扱われるため、justify-items
プロパティや justify-self
プロパティに相当するものはありません。しかし、フレックスボックスと併せて auto マージンを使ってアイテム毎の配置をすれば、個別のアイテムまたは一部アイテムのグループを他のアイテムから分離して配置することができます。
よくあるパターンは、ナビゲーションバーでいくつかのキーアイテムが右に配置され、メイングループは左に配置されるようなものです。このようなケースは justify-self
プロパティの使いどころだと思われるでしょうが、以下の図について考えてみましょう。3 つのアイテムが片方にあり、もう一方に 2 つのアイテムがあります。もし仮に justify-self
をアイテム d に対して使うことができたとすると、意図したものであってもそうでなくても、それに続くアイテム e の配置も変わってしまうでしょう。
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
プロパティは、両方を一緒に設定する一括指定です。