In 'n' Out

知識を取り込み、そして発信する

flex・gridの中身を整える

flex・gridで中身のそろえ方を指定する

flexやgridを使うと、要素を横や縦に並べることは簡単にできます。
しかし実際のレイアウトでは、並んだ要素をどこに寄せるか、どうそろえるかまで指定する必要があります。
ここでは、要素を1つずつ動かすのではなく、並び方そのものを整えるための指定方法をまとめて扱います。
flexとgridのどちらでも使えるもの、片方だけに用意されているものを整理しながら、レイアウトを安定してコントロールするための考え方を確認していきます。

並び方の概念

並び方を調整するプロパティには、まとまりを整えるものと、各要素を整えるものがあります。
これらを正しく使い分けるために、まずは並び方の概念を整理しておきましょう。

justifyとalign

flexとgridではjustifyとalignの基準となる向きが異なります。
flexは並べ方をflex-directionプロパティで、row(横)かcolumn(縦)か値を決められます。
そのため、決めた並べ方によりjustifyとalignの方向が変わります。

flex-direction:rowの場合
flex-direction:columnの場合

このように、flex-directionで決めた並び方の向きがjustify、並びと違う向きがalignです。
一般的には、justifyを主軸、alignを交差軸と呼びます。
flexでは、flex-directionによって主軸と交差軸の向きが変わります。

一方でgridはjustifyは横方向が主軸、alignは縦方向が交差軸と決まっています。

gridの場合

flexとgridでjustifyとalignの意味合いが異なるのは、この違いによるものです。

集まりと単品で考える並び方の調整

justifyとalignの向きの違いを理解したうえで、次に整理しておきたいのが、どこを対象に並び方を調整しているのかという視点です。
content系プロパティは、並んだ要素そのものではなく、要素の集まり全体をどこに配置するかを指定します。
コンテナ内に余白がある場合に、その余白を開始位置に寄せるのか、中央にまとめるのか、間隔として分配するのかを決めるための指定です。

items系プロパティは、並んだ要素一つ一つの配置を整えるための指定です。
各要素が割り当てられた領域の中で、開始位置に寄せるのか、中央に配置するのか、領域いっぱいに広げるのかといった調整を行います。
content系が集まり全体を対象にするのに対し、items系は各要素を対象にする点が決定的な違いです。

content系とitems系という考え方自体は、flexとgridで共通しています。
ただし、実際に使用できるプロパティは、flexとgridで異なります。

プロパティ一覧
プロパティflex・grid役割の概要
justify-content共用要素の集まりを主軸方向に配置する
align-content共用複数行・列の集まりを交差軸方向に配置する
place-content共用主軸・交差軸をまとめて指定する
justify-itemsgrid専用各要素を横方向に配置する
align-items共用各要素を縦方向に配置する
place-itemsgrid専用各要素の配置をまとめて指定する

すべてのプロパティを同じ深さで扱うと、条件や制約の説明が膨らみすぎてしまうため、このあとのflex・gridでは、実務で使用頻度が高く、挙動が安定しているものに絞って解説します。

flexの並び方の調整

flexでは、要素の並び方を調整するためにjustify-contentとalign-itemsを使用します。
どちらも「要素そのもの」ではなく、「要素の集まり」をどう配置するかを制御するプロパティです。

justify-content

構文

セレクタ{
    justify-content:値;
}

justify-contentは、要素の集まりを、並ぶ向きでそろえるためのプロパティです。

値一覧(抜粋)
挙動注意点使用頻度
flex-start開始位置に揃える余白がある場合のみ違いが出る
flex-end終了位置に揃える逆方向に寄るため意図を誤解しやすい
center中央に揃える主軸の向きに注意が必要
stretch空いている領域いっぱいに広げて配置するサイズ指定があると効かない
space-between両端に揃えつつ間隔を均等にする要素数が少ないと極端になる
space-around間隔を均等にして両端は半分にする見た目が不安定になりやすい
space-evenlyすべての間隔を均等にする対応ブラウザと見た目確認が必要

一覧表より頻度が高いflex-start・center・space-betweenを扱います。

コード例

<h4 id="flex-start">flex-start</h4>
<div class="flex-row">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<div class="flex-column">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<h4 id="flex-center">flex-start</h4>
<div class="flex-row">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<div class="flex-column">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<h4 id="flex-space-between">space-between</h4>
<div class="flex-row">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<div class="flex-column">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
div {
    background-color: #eeeeee;
    display: flex;
    margin-bottom: 8px;
}

p{
    border: 1px solid #000000;
    box-sizing: border-box;
}

.flex-column{
    flex-direction: column;
    height: 160px;
}

#flex-start ~ .flex-row,  #flex-start ~ .flex-column {
    justify-content: start;
}

#flex-center ~ .flex-row,  #flex-center ~ .flex-column {
    justify-content: center;
}

#flex-space-between ~ .flex-row,  #flex-space-between ~ .flex-column {
    justify-content: space-between;
}

出力例

flex-start

要素1

要素2

要素3

要素4

要素1

要素2

要素3

要素4

flex-center

要素1

要素2

要素3

要素4

要素1

要素2

要素3

要素4

space-between

要素1

要素2

要素3

要素4

要素1

要素2

要素3

要素4

この例では、同じ要素構造に対して並ぶ向き(row・column)だけを切り替え、justify-contentがどの方向に影響するかを比較しています。
flex-row では横方向に要素が並ぶため、justify-content は左右方向の配置を調整します。
一方、flex-column では縦方向に並ぶため、justify-content は上下方向の配置を調整します。
このように、justify-content は「並んでいる向き(主軸)」に沿って、要素の集まり全体の位置関係を決めるプロパティです。

align-items

構文

セレクタ{
    align-items:値;
}

align-itemsは、要素の集まりを、並びと違う向きでそろえるためのプロパティです。

値一覧(抜粋)
挙動注意点使用頻度
start開始位置に揃える高さや幅に余白がある場合のみ差が出る
end終了位置に揃える逆方向に寄るため意図を誤解しやすい
center中央に揃える交差軸の向きを誤解しやすい
stretch空いている領域いっぱいに広げて配置するサイズ指定があると効かない

一覧表より頻度が高いcenter・stretchを扱います。
なお、align-itemsではspace-betweenなどの間隔系の値は使用できません。

コード例

<h4 id="center">center</h4>
<div class="flex-row">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<div class="flex-column">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<h4 id="stretch">stretch</h4>
<div class="flex-row">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<div class="flex-column">
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
div{
    background-color: #eeeeee;
    display: flex;
    margin-bottom: 8px;
}

p{
    border: 1px solid #000000;
    box-sizing: border-box;
}

.flex-row{
    height: 60px;
}

.fai02-17 .flex-column {
    flex-direction: column;
    width: 200px;
    height: 160px;
}

#center ~ .flex-row, #center ~ .flex-column{
    align-items: center;
}

#flex-stretch ~ .flex-row, #flex-stretch ~ .flex-column {
    align-items: stretch;
}

出力例

center

要素1

要素2

要素3

要素4

要素1

要素2

要素3

要素4

stretch

要素1

要素2

要素3

要素4

要素1

要素2

要素3

要素4

centerを指定するとrowの場合は要素は縦方向の中央にそろい、columnの場合は要素は横方向の中央にそろいます。 この違いは、align-itemsが「縦にそろえるプロパティ」「横にそろえるプロパティ」ではなく、交差軸に対してそろえるプロパティであるためです。
stretchを指定するとrowの場合は各要素の高さが揃って親の高さに広がり、columnの場合は各要素が幅いっぱいに広がっています。
子要素に高さや幅が指定されていない場合、自動的に親のサイズに合わせて引き伸ばされています。

gridの並び方の調整

gridでは、行と列で作られたマス目の中に要素が配置されます。
その際、各マス目の中で要素をどこに寄せるかを指定するのが、items系プロパティです。

justify-items

構文

セレクタ{
    justify-items:値;
}

justify-itemsは、各要素を横方向にどう配置するかを指定するプロパティです。
gridでは横方向が常にjustifyの対象となるため、flexのように向きを意識して考える必要はありません。

値一覧(抜粋)
挙動注意点使用頻度
start各要素を割り当てられた列の開始位置に寄せて配置する列に余白がある場合にのみ見た目の変化が現れる
end各要素を割り当てられた列の終了位置に寄せて配置する左右の向きを直感的に把握しづらく、意図が伝わりにくい
center各要素を割り当てられた列の中央に配置するjustifyは横方向に作用する点を理解していないと混乱しやすい
stretch要素を列の幅いっぱいに広げて配置する子要素に幅指定がある場合は効果が現れない

一覧表より頻度が高いstart・centerを扱います。

コード例

<h4 id="grid-start">start</h4>
<div>
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<h4 id="grid-justify-center">center</h4>
<div>
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
div{
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
    background-color: #eeeeee;
    height: 80px;
}

p{
    border: 1px solid #000000;
    box-sizing: border-box;
}

#grid-start ~ div{
    justify-items: start;
}

#grid-justify-center ~ div {
    justify-items: center;
}

出力例

start

要素1

要素2

要素3

要素4

center

要素1

要素2

要素3

要素4

startを指定すると各要素は、それぞれ割り当てられた列の中で横方向の左に配置されます。
centerを指定すると各要素は、それぞれ割り当てられた列の中で横方向の中央に配置されます。
要素同士の間隔を変えているわけではなく、マス目の中での位置だけが変わっている点が重要です。

align-items

構文

セレクタ{
    align-items:値;
}

align-itemsは、各要素を縦方向にどう配置するかを指定するプロパティです。
gridでは縦方向がalignの対象として固定されています。

値一覧(抜粋)
挙動注意点使用頻度
start各要素を割り当てられた行の開始位置に寄せて配置する行に高さの余白がない場合は違いが分かりにくい
end各要素を割り当てられた行の終了位置に寄せて配置する上下の基準を誤解しやすく、意図が読み取りにくい
center各要素を割り当てられた行の中央に配置する縦方向に作用するプロパティである点を意識する必要がある
stretch要素を行の高さいっぱいに広げて配置する子要素に高さ指定があると効果が出ない

一覧表より頻度が高いcenter・stretchを扱います。

コード例

<h4 id="grid-align-center">center</h4>
<div>
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
<h4 id="grid-stretch">stretch</h4>
<div>
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>
</div>
div{
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
    background-color: #eeeeee;
    height: 150px;
}

p{
    border: 1px solid #000000;
    box-sizing: border-box;
}

#grid-align-center ~ div{
    align-items: center;
}

#grid-stretch ~ div {
    align-items: stretch;
}

出力例

center

要素1

要素2

要素3

要素4

stretch

要素1

要素2

要素3

要素4

centerを指定すると各要素は、それぞれ割り当てられた行の中で縦方向の中央に配置されます。
stretchを指定すると各要素は、それぞれ割り当てられた列の中で高さ一杯に広がって配置されます。
なお、content系は使用頻度が低い上に条件・制約が厳しいため、当サイトでは取り扱いません。

grid-templateを用いた調整

grid-template-columnsやgrid-template-rowsでは、行や列の数とサイズを明示的に指定できます。
一方で、画面サイズに応じて「ある程度まで縮めたい」「余白があれば広げたい」といった調整は、固定値だけでは対応しきれません。
こうした調整を、grid-templateの指定の中で行うために用意されている値が、minmax・auto-fit・auto-fill です。
これらは要素の配置を変える指定ではなく、グリッドの列や行がどのように振る舞うかを決めるための仕組みとして使われます。

minmax

minmaxは、gridの列や行に最小値と最大値の幅(高さ)を同時に指定できる値です。
固定と可変を組み合わせた、柔軟なグリッド設計に使われます。

構文

セレクタ{
    grid-template-columns:minmax(最小値, 最大値);
    grid-template-rows:minmax(最小値, 最大値);
}

minmaxの最小値にはこれ以上縮まないサイズを、最大値には広がる上限となるサイズを指定します。
最大値にはfrを指定できるため、画面サイズに応じて伸縮するレイアウトを作れます。

コード例

<div>
    <p>要素1</p>
    <p>要素2</p>
    <p>要素3</p>
    <p>要素4</p>

</div>
div{
    display: grid;
    grid-template-columns: repeat(2, minmax(100px, 1fr));
    grid-template-rows: repeat(2, minmax(60px, 1fr));
    background-color: #eeeeee;
    gap: 10px;
}

p{
    border: 1px solid #000000;
    box-sizing: border-box;
}

出力例

要素1

要素2

要素3

要素4

普通の表示ではないかと思うでしょうが、画面が狭い場合でも各列は100px、各行は1fr未満には縮まりません。
最大値にfrを指定することで、余白を均等に分配しながら列を広げることができます。
minmaxは、レスポンシブ対応の基礎として非常に重要で、後述するauto-fit・auto-fillと組み合わせることで真価を発揮します。

auto-fit

auto-fitは、repeatと組み合わせて使い、要素数に応じて列数を自動調整するための指定です。

構文

セレクタ{
    grid-template-columns:repeat(auto-fit, minmax(最小値, 最大値));
    grid-template-rows:repeat(auto-fit, minmax(最小値, 最大値));
}

auto-fitは、入るだけ列を作り、余った列は詰めて消すという挙動をします。

コード例

<div id="auto-fit">
    <div>
        <img src="img/animal-01.png">
        <p>ネズミ</p>
    </div>
    <div>
        <img src="img/animal-02.png">
        <p>ウシ</p>
    </div>
    <div>
        <img src="img/animal-03.png">
        <p>トラ</p>
    </div>
    <div>
        <img src="img/animal-04.png">
        <p>ウサギ</p>
    </div>
    <div>
        <img src="img/animal-05.png">
        <p>リュウ</p>
    </div>
    <div>
        <img src="img/animal-06.png">
        <p>ヘビ</p>
    </div>
</div>
#auto-fit {
    width: 100%;
    background: #f7cdf5;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 15px;
    text-align: center;
}

#auto-fit div {
    border: 1px solid #000000;
    box-sizing: border-box;
    text-align: center;
}

p{
    margin: 0;
    padding: 0;
}

img{
    margin: 0 auto;
}

出力・動作例

画面幅に応じて列数が増減し、要素が少ない場合は余白を詰めて広がります。
カード型レイアウトや一覧表示では、auto-fitを使うことで自然な横並びが実現できます。
なお、grid-template-rowsにも使用できますが、高さがコンテンツに依存しやすく、意図しない余白やズレが発生しやすいため、実務では使用場面が限られます。

auto-fill

auto-fillはauto-fitと似ていますが、空の列を残したまま配置する点が異なります。

構文

セレクタ{
    grid-template-columns:repeat(auto-fill, minmax(最小値, 最大値));
    grid-template-rows:repeat(auto-fill, minmax(最小値, 最大値));
}

auto-fillは、入るだけ列を作り、要素が足りなくても列そのものは保持します。

コード例

<div id="auto-fill">
    <div>
        <img src="img/animal-01.png">
        <p>ネズミ</p>
    </div>
    <div>
        <img src="img/animal-02.png">
        <p>ウシ</p>
    </div>
    <div>
        <img src="img/animal-03.png">
        <p>トラ</p>
    </div>
    <div>
        <img src="img/animal-04.png">
        <p>ウサギ</p>
    </div>
    <div>
        <img src="img/animal-05.png">
        <p>リュウ</p>
    </div>
    <div>
        <img src="img/animal-06.png">
        <p>ヘビ</p>
    </div>
</div>
#auto-fill {
    width: 100%;
    background: #f7cdf5;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 15px;
    text-align: center;
}

#auto-fit div {
    border: 1px solid #000000;
    box-sizing: border-box;
    text-align: center;
}

p{
    margin: 0;
    padding: 0;
}

img{
    margin: 0 auto;
}

出力・動作例

要素数が少ない場合でも列の枠は残るため、余白が発生しやすいレイアウトになります。
このため、実務ではauto-fillよりもauto-fitが選ばれるケースが多くなります。

なお、auto-fitやauto-fillは列や行に固定幅・固定高さを指定している場合は自動的な調整が行われません。
また、grid-template-rowsで使用すると高さがコンテンツに依存しやすいため、実務ではgrid-template-columnsに対して使われるのが一般的です。