フレックスコンテナー内のアイテムの配置
フレックスボックスが有用な理由の 1 つは、要素を垂直方向に中央揃えする手軽な方法を提供しているなど、適切な配置が可能になることです。このガイドでは、フレックスボックスの配置と位置揃えのプロパティがどのように動作するのかを、徹底的に見ていきます。
フレックスボックスでの配置の使用
フレックスボックスには配置と余白を制御するプロパティがいくつか提供されており、 align-items
と justify-content
は要素を中央揃えにするための基本的なプロパティです。要素を中央に配置するには、 align-items
プロパティを使用してアイテムを交差軸(この場合は縦方向に動作するブロック軸)に配置します。 justify-content
を使用して、主軸(この場合は水平方向に動作するインライン軸)に配置します。
下記のコード例で、コンテナー内または内側の要素のサイズを変更してみてください。内側の要素は常に中央に配置されます。
<div class="box">
<div></div>
</div>
.box {
display: flex;
align-items: center;
justify-content: center;
border: 2px dotted rgb(96 139 168);
}
.box div {
width: 100px;
height: 100px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
配置を制御するプロパティ
本ガイドで扱うプロパティは以下のとおりです。
justify-content
: 全アイテムの主軸上の配置を制御します。align-items
: 全アイテムの交差軸上の配置を制御します。align-self
: 個別のフレックスアイテムごとに交差軸上の配置を制御します。align-content
: 仕様では「フレックス行のパッキング (packing flex lines)」と説明されている。交差軸上でのフレックス行間の余白を制御します。gap
,column-gap
,row-gap
: フレックスアイテム間にすき間または溝を生成するために使用します。
また、auto マージンがフレックスボックスでの配置にどのように使えるかについても触れます。
交差軸上のアイテムの配置
フレックスコンテナー内で設定する align-items
プロパティと、フレックスアイテムで設定する align-self
プロパティは、フレックスアイテムの交差軸上の配置を制御します。交差軸は、 flex-direction
が row
の場合は列に、 flex-direction
が column
の場合は行に沿って流れます。
基本的なフレックスの例で、交差軸上の配置を使用してみましょう。 display: flex
をコンテナーに設定すると、子要素はすべてフレックスアイテムになり、一行に配置されます。既定では、このフレックスアイテムはすべて、最も背の高いアイテムと同じ高さになるように引き伸ばされますので、最も背の高いアイテムが交差軸のアイテムの高さを定義することになります。フレックスコンテナーに高さが設定されている場合は、アイテム内のコンテンツの大きさにかかわらず、コンテナーの高さまで各アイテムが引き伸ばされます。
アイテムが同じ高さになるのは、交差軸での配置を制御する align-items
プロパティの初期値が stretch
となっているためです。
アイテムの配置を制御するために、以下の値を使うことができます。
align-items: stretch
align-items: flex-start
align-items: flex-end
align-items: start
align-items: end
align-items: center
align-items: baseline
align-items: first baseline
align-items: last baseline
以下の例では、align-items
の値は stretch
に設定されています。他の値についても試し、フレックスコンテナーの中でそれぞれのアイテムが互いにどのように配置されるかを確認してください。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three <br />には追加の<br />テキストが<br />あります</div>
</div>
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: stretch;
}
.box div {
width: 100px;
height: 100px;
background-color: rgb(96 139 168 / 0.2);
border: 2px solid rgb(96 139 168);
border-radius: 5px;
}
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
の値を変更して、これがどのように動作するのか確認してみてください。
<div class="box">
<div>One</div>
<div>Two</div>
<div class="selected">Three</div>
<div>Four</div>
</div>
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
align-items: flex-start;
height: 200px;
}
.box div {
background-color: rgb(96 139 168 / 0.2);
border: 2px solid rgb(96 139 168);
border-radius: 5px;
padding: 20px;
}
.box > *:first-child {
align-self: stretch;
}
.box .selected {
align-self: center;
}
主軸の変更
ここまで、flex-direction
が既定でrow
に設定されている場合の配置動作について見てきましたが、これは上から下へ書く言語で、横が主軸、縦が交差軸で作業している場合について見てみましょう。
同じ書字方向のままで、 flex-direction
を column
に変更すると、 align-items
と align-self
プロパティではアイテムを上下ではなく左右に配置します。これらのプロパティはアイテムを交差軸に沿って配置することに変わりはありませんが、交差軸はこれで水平になります!
次の例では flex-direction: column
を設定し、それ以外は先の例と全く同じフレックスコンテナーを使ってこの動作を示しています。
<div class="box">
<div>One</div>
<div>Two</div>
<div class="selected">Three</div>
<div>Four</div>
</div>
.box {
border: 2px dotted rgb(96 139 168);
display: flex;
flex-direction: column;
align-items: flex-start;
width: 200px;
}
.box div {
background-color: rgb(96 139 168 / 0.2);
border: 2px solid rgb(96 139 168);
border-radius: 5px;
padding: 20px;
}
.box > *:first-child {
align-self: stretch;
}
.box .selected {
align-self: center;
}
align-content
プロパティによるコンテンツの交差軸への配置
これまでは、 1 行のフレックスアイテムを含むフレックスコンテナーの中に、アイテムや個々のアイテムを配置することを中心に説明してきました。フレックスアイテムが複数行にまたがる場合、 align-content
プロパティを使用して行間の余白の配分を制御することができます。これはフレックス行のパックと呼ばれます。
align-content
が有効に動作するためには、フレックスコンテナーの交差軸の寸法(この場合は高さ)が、アイテムを表示するのに必要な寸法より大きくなければなりません。これはすべてのアイテムに対して一括で動作します。 align-content
の値は、利用できる余った空間と、その中の一連のアイテム全体の配置を決定します。
align-content
プロパティには以下の値を設定できます。
align-content: flex-start
align-content: flex-end
align-content: start
align-content: end
align-content: center
align-content: space-between
align-content: space-around
align-content: space-evenly
align-content: stretch
align-content: normal
(stretch
として動作)align-content: baseline
align-content: first baseline
align-content: last baseline
以下の例では、フレックスコンテナーは 400 ピクセルの高さで、アイテムを表示するのに必要な高さよりも高くなっています。 align-content
の値は space-between
で、この場合は残る分配可能な余白 (available space) はフレックス行の間に分配され、フレックス行自体はコンテナーの交差軸上の始点と末尾に密着して配置されます。
align-content
プロパティがどのように働くか、ほかの値を設定して確認してください。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div>Eight</div>
</div>
.box {
width: 450px;
border: 2px dotted rgb(96 139 168);
display: flex;
flex-wrap: wrap;
height: 300px;
align-content: space-between;
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
flex: 1 1 100px;
}
.box div {
background-color: rgb(96 139 168 / 0.2);
border: 2px solid rgb(96 139 168);
border-radius: 5px;
padding: 20px;
}
列に沿った軸の時にこのプロパティの効果がどのように変わるか、 flex-direction
を column
に変更した場合について確認してください。変更前と同様に、すべてのアイテムを表示した上で、十分な余白が交差軸上に必要です。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div>Eight</div>
</div>
.box {
display: flex;
flex-wrap: wrap;
flex-direction: column;
width: 400px;
height: 300px;
align-content: space-between;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
flex: 1 1 100px;
}
.box div {
background-color: rgb(96 139 168 / 0.2);
border: 2px solid rgb(96 139 168);
border-radius: 5px;
padding: 20px;
}
主軸上での配置
ここまで交差軸上での配置がどのように動くかを見てきましたが、ここでは主軸上での配置について見ていきます。使えるプロパティは justify-content
の一つだけです。アイテムは主軸上ではグループとしてのみ扱われるため、プロパティも一種類となります。 justify-content
では、アイテムを表示するのに必要な分よりも大きい空間がある場合の分配可能な余白の扱いを制御できます。
コンテナーに display: flex
を設定した最初の例では、アイテムはコンテナーの始点に一行に整列して表示されます。これは justify-content
の初期値が normal
であり、これは start
として動作するためです。すべての分配可能な余白はアイテムの後ろに置かれます。
baseline
の値はこの軸には関連ありません。 justify-content
プロパティは align-content
と同じ値を受け付けます。
justify-content: flex-start
justify-content: flex-end
justify-content: start
justify-content: end
justify-content: left
justify-content: right
justify-content: center
justify-content: space-between
justify-content: space-around
justify-content: space-evenly
justify-content: stretch
(start として動作)justify-content: normal
(stretch として動作し、これは start として動作する)
次の例では、 justify-content
の値は space-between
となっています。アイテムを表示した後に余った分配可能な余白は、アイテムの間に分配されます。左右の端のアイテムはそれぞれ始点と末尾に揃えて並びます。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
.box {
display: flex;
justify-content: space-between;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
flex-direction
が column
に設定されて主軸がブロック方向となっているとき、justify-content
はフレックスコンテナー内の分配可能な余白があれば、アイテム間にその方向にそって余白を分配します。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
.box {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 300px;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
配置と書字方向
上述の配置方法において、start
と end
はいずれも書字方向に対応したものとなります。 justify-content
の値が start
で、書字方向が英語のような左書きであれば、アイテムはコンテナーの左端から並べられます。
一方で書字方向がアラビア語のように右から左であれば、アイテムはコンテナーの右端から並べられます。
以下の例ではフレックスアイテムを右から左に並べるために direction
プロパティを rtl
を設定しています。この設定を削除したり justify-content
の値を変更するなどして、行が右から始まる場合のフレックスボックスの動作を確認してください。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
.box {
direction: rtl;
display: flex;
justify-content: flex-end;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
配置と flex-direction
flex-direction
プロパティを変更した場合にも、行の start
の方向は変わります。例えば row
の代わりに row-reverse
を設定した場合などです。
この例では、 flex-direction: row-reverse
と justify-content: flex-end
で、フレックスコンテナー内でアイテムの向きと位置を定義しています。左書きの言語では、アイテムは左に並びます。 flex-direction: row-reverse
を flex-direction: row
に変更してみてください。これでアイテムが右側に移され、視覚的な順序が逆になることがわかります。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
</div>
.box {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
こうした動作は少し紛らわしいかもしれませんが、覚えておくべき原則として、何かを変更しない限りは、文書の言語において単語が配置される方向にインライン軸、行方向の軸に沿ってフレックスアイテムが配置されます。 start
と flex-start
は文の中でテキストの先頭側から始まることになります。
flex-direction: column
を使うことで、アイテムの配置方向を文書の言語におけるブロック方向に変更することもできます。この場合は start
と flex-start
は段落が始まる先頭を示すことになります。
flex-direction
を逆方向の値のいずれかに変更すると、軸の末尾側から文書の言語において単語が書かれる方向と逆方向にレイアウトされます。 start
と flex-start
はその軸の末尾側、つまりインライン方向では行を折り返す側、ブロック方向では最後の文が終わる側を示すことになります。
auto マージンを使用した主軸上での配置
主軸上ではアイテムは一つのグループとして扱われるため、justify-items
プロパティや justify-self
プロパティに相当するものはありません。しかし、フレックスボックスと併せて auto マージンを使ってアイテム毎の配置をすれば、個別のアイテムまたは一部アイテムのグループを他のアイテムから分離して配置することができます。
よくあるパターンは、ナビゲーションバーでいくつかのキーアイテムが右に配置され、メイングループは左に配置されるようなものです。このようなケースは justify-self
プロパティの使いどころだと思われるでしょう。しかし、以下の図について考えてみましょう。この例では、次の図のように、 3 つのアイテムが片方にあり、もう一方に 2 つのアイテムがあります。もし仮に justify-self
をアイテム d に対して使うことができたとすると、意図したものであってもそうでなくても、それに続くアイテム e の配置も変わってしまうでしょう。
代わりに、 d のアイテムを CSS マージンによって押しやることができます。
このライブサンプルでは、アイテム 4 の margin-left
を auto
に設定することで、最初の 3 つのアイテムから分離し、その軸にあるすべての余白を消費しています。これは、 margin
で左右を auto にしてブロックを中央に配置する動作と同じ仕組みです。それぞれの辺はできる限りの空間を取ろうとするので、ブロックは中央へ押し込まれます。
このライブサンプルでは、フレックスアイテムは基本的なフレックス値で 1 行に並べられており、4 番目のアイテムに設定したクラス push
は、そのアイテムに margin-left: auto
を適用しています。 4 番目のアイテムのクラスを取り除くか、別のアイテムにクラスを追加して、どのように動作するのか試してみてください。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div class="push">Four</div>
<div>Five</div>
</div>
.box {
display: flex;
border: 2px dotted rgb(96 139 168);
}
.box > * {
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}
.push {
margin-left: auto;
}
アイテム間にすき間を作成
フレックスのアイテム間にすき間を作るには、gap
、column-gap
、row-gap
の各プロパティを使用します。column-gap
プロパティは、行内のアイテム間にすき間を作成します。row-gap
プロパティは、flex-wrap
が wrap
に設定されている場合、フレックス行間にすき間を作成します。
gap
プロパティは、 row-gap
と column-gap
の両方を一緒に設定する一括指定です。
フレックスアイテム間またはフレックス行間の隙間は方向によって変わります。 flex-direction
プロパティが行を作成する場合、最初の値はフレックス行間の隙間を定義し、 2 つ目の値はそれぞれの行内のアイテム間の隙間を定義します。列の場合(flex-direction
を column
または column-reverse
に設定した場合)、最初の値はフレックスアイテム間の隙間を定義し、 2 つ目の値はフレックス行間の隙間を定義します。
<div class="box">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
<div>Six</div>
</div>
.box {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
column-gap: 2em;
border: 2px dotted rgb(96 139 168);
}
.box > * {
flex: 1;
padding: 20px;
border: 2px solid rgb(96 139 168);
border-radius: 5px;
background-color: rgb(96 139 168 / 0.2);
}