フレックス・ボックス(Flex Box)とは何か
フレックス・ボックスは、CSSで操作可能なレイアウト・モデルの一種です。正確にはフレックス・ボックス・モジュール(Flexible Box Module)と言います。この機能を使用すると、通常のフローでは実現が難しい横並びの配置やレスポンシブデザインの対応が簡単に行えます。
フレックス・ボックスのモデルでは、コンテナとアイテムという二つの関係性を扱います。まずは基本を押さえてから、必要となるプロパティの操作を学んでいきましょう。
以降の内容を読み進める前に、CSSのボックス・モデルについて把握しておくとスムーズに理解できます。ボックス・モデルは、CSSがHTMLの要素をどのように扱うのかを表す基本的な概念です。この仕組みの拡張機能の一種が、フレックス・ボックスなのです。
フレックス・ボックスを開始する
フレックス・ボックスの作成手順は非常に簡単です。フレックス・ボックスのレイアウトを適用したい要素にdisplay
プロパティを追加し、その値にflex
またはinline-flex
を指定します。
これで下準備が整いました。あとは必要な数だけ子要素を配置し、期待通りのレイアウトに整えていくだけです。フレックス・ボックスの記述内容はそれほど複雑ではありませんが、コンテナやアイテムといった多くの用語が登場するため、言葉の意味を事前に把握しておくことを推奨します。
HTMLとCSSの基本的な構成は以下の通りです。
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
</div>
.container {
display: flex;
/* コンテナに指定するプロパティ */
}
.item {
/* アイテムに指定するプロパティ */
}
コンテナとアイテムについて
フレックス・ボックスでは、コンテナとアイテムという二つの主従関係を扱います。コンテナというのはアイテムを包含する親要素、アイテムはコンテナに含まれる子要素です。
コンテナは、display
プロパティの値にflex
またはinline-flex
が指定された要素です。この状態の要素は、コンテンツ・ボックスの内部空間にフレックス・ボックスのレイアウトを適用します。これは通常のフローとは別のルールで子要素が配置されることを意味します。
そしてフレックス・コンテナの直下に配置された子要素は、自動的にフレックス・アイテムとして扱われます。フレックス・アイテムにするために、何か特別なCSSを追記する必要はありません。
以下の例を操作してみましょう。display
プロパティの値がblock
の場合、子要素は通常のフローに従って配置されます。その値をflex
に変更すると、どのように表示されるでしょうか。
フレックス・コンテナに配置された子要素は、display
プロパティの値がflex
になった時点で、自動的に横並びになります。これはフレックス・ボックスのレイアウトに関わるプロパティが有効になり、その全てに初期値が適用されるからです。
コンテナに指定できるプロパティとアイテムに指定できるプロパティには、それぞれ別の役目があります。それらを実際に扱う前に、コンテナとアイテムの関係性を理解しておくことが重要です。
主軸と交差軸について
要素にdisplay
プロパティのflex
を適用すると、ボックスの空間に主軸(main axis)と交差軸(cross axis)が生まれます。既定値では主軸が行方向の並び、交差軸が主軸と垂直に交わる列方向の並びとなります。
主軸の方向は、flex-direction
プロパティで定義します。つまり、指定する値を変えると主軸の方向やアイテムの並び方が変わります。既定値ではrow
になっているため、省略すると文字と同じ並び方になります。
flex-direction
は書字方向と深く関係しています。フレックス・コンテナのプロパティを一切変えなくとも、ドキュメントの書字方向を変えると、主軸の方向やアイテムの並び方が変わります。
書字方向は、direction
プロパティやwriting-mode
プロパティで定義しますが、英文や日本語を扱っている限り、文章は左から右へ並び、上から下へ積み重なる配置が一般的です。
以下の例は、flex-direction
プロパティの値を変更した時に、主軸の方向とアイテムの並び方がどのように変わるのかを示すものです。プルダウン式のセレクトメニューを操作して、実際に確かめてみましょう。
先頭と末尾について
フレックス・ボックスの行には、先頭と末尾という考え方があります。先頭は、その文書の書字方向において文字が先に書かれる方向の端。そして末尾は、文字列が後ろに続いていく方向の端です。
ここで重要なのは、画面に向かって左や右という表現を使わないということです。例えば、direction
プロパティの値がltr
(Left To Right)の言語圏では、左から右へ向かって文章が書かれるため、フレックス行の左端が先頭、フレックス行の右端が末尾になります。
これがアラビア語などの言語圏で使われるrtl
(Right To Left)になると、先頭と末尾の位置が入れ替わり、アイテムの並ぶ順序が逆転します。つまり、flex-direction
プロパティの値が同じrow
であっても、アイテムの並び方は先頭と末尾を参照するため、左や右という表現では正確性を担保できないのです。
以下の例は、フレックス・ボックスの挙動がdirection
プロパティの値によって変化することを示すものです。コンテナによって制御されるアイテムの並びや寄せ方が変わることを確認して下さい。
ひとつ前の項目で示したサンプルの中にrow-reverse
とcolumn-reverse
という値がありますが、これは書字方向を固定したまま、アイテムの並び順を逆にできる機能です。
フレックス・コンテナを理解する
フレックス・ボックスのレイアウトが適用される範囲のことを、フレックス・コンテナと呼びます。これは単に、display
プロパティの値にflex
もしくはinline-flex
が指定された要素のことを指す場合もあります。
いずれにせよ、フレックス・コンテナは複数の子要素を包含する親要素です。そしてコンテナの直下に配置された子要素のことを、自動的にアイテムとして扱います。
flex-direction
flex-direction
プロパティは、フレックス・ボックスのレイアウト全体に関わる主軸の方向とアイテムの並び順を定義します。既定値では、ここにrow
が適用されるため、主軸は水平方向、アイテムは文字と同じ順序で並びます。
flex-direction
の値を変更した場合の挙動は、主軸と交差軸の項目で解説しています。
.container {
display: flex;
flex-direction: column;
}
flex-wrap
flex-wrap
プロパティは、アイテムの寸法の合計値がコンテナに収まりきらない場合に、それを折り返すのか折り返さないのかを定義します。既定値では、ここにnowrap
が適用されるため、アイテムは折り返されずに行を増やしません。
アイテムが折り返されると、コンテナの中に新しい行が追加されます。その行は、各々が独立したフレックス・ボックスとして扱われるため、交差軸に並んだアイテムの寸法は連動しません。
.container {
display: flex;
flex-wrap: wrap;
}
flex-flow
flex-flow
プロパティは、flex-direction
とflex-wrap
の値を一括で操作するショートハンド・プロパティです。ひとつ目の値で主軸方向とアイテムの並び順を定め、二つ目の値で折り返す方法を定義します。
いずれかの値を省略することも可能です。省略された値には初期値が適用されます。
.container {
display: flex;
flex-flow: row wrap;
}
justify-content
justify-content
プロパティは、フレックス・コンテナの主軸に対してアイテムをどこに寄せるのかを指定します。これは同じフレックス行を共有するアイテムの寄せ方、あるいは余白の分配を定義するものです。
アイテムの中にひとつでも伸長するものがあれば、余白を全て埋めようとするためjustify-content
の効果は無効となります。
.container {
display: flex;
justify-content: space-between;
}
align-items
align-items
プロパティは、フレックス・コンテナの交差軸に余白がある場合に、アイテムをどこに寄せるのかを指定します。この機能は、全てのアイテムに対してalign-self
を指定する場合と同じ効果をもたらします。
.container {
display: flex;
align-items: center;
}
align-content
align-content
は、アイテムが複数行に渡って並ぶ場合の揃え位置を指定します。この機能はコンテナの交差軸の寸法に余裕があり、アイテムの並びが複数行に渡っている場合にのみ有効です。そのため、flex-wrap
の値がnowrap
である場合は効果が現れません。
既定値ではstretch
が適用されているため、アイテムの交差軸の寸法が自動的に伸縮します。start
やend
の位置指定は、フレックス・ボックスの先頭と末尾の概念に対応しています。
.container {
display: flex;
flex-wrap: wrap;
align-content: start;
}
gap
gap
プロパティは、隣接するアイテム同士の間隔を指定します。このプロパティは、列方向の隙間を操作するcolumn-gap
プロパティと、行方向の隙間を操作するrow-gap
プロパティのショートハンドです。
ひとつ目の値がrow-gap
、二つ目の値がcolumn-gap
を表しますが、二つ目の値を省略すると両方が同じ寸法であるとみなされます。
この機能の特徴は、アイテム同士が隣接する空間のみに作用する点です。基本的にはコンテナの内側に向いている辺にしか隙間を与えません。アイテムの辺とコンテナの辺が隣接する外側の隙間には影響を与えないということです。
これまで、アイテム同士の隙間をmargin
で操作していた場合、レスポンシブデザインなどでレイアウトが変化した時に、余白が過剰になるケースがありました。この問題は、多くの場合gap
を使うことで解消できます。
.container {
display: flex;
gap: 1rem;
}
フレックス・アイテムを理解する
フレックス・ボックスのレイアウトが適用される範囲に属している子要素のことを、フレックス・アイテムと呼びます。アイテムであるかどうかを定義するのは、親要素のdisplay
プロパティであるため、アイテム自身に何か特別なプロパティを付加する必要はありません。
アイテム自身に指定するプロパティは、同じフレックス・ボックスに属するアイテム同士の相対的な関係の中で、自身がどのように振る舞うのかを定義するものです。個別の指定が必要ない場合は、コンテナ側で制御できるため、機能的な役割りを整理しておくと理解しやすいでしょう。
flex-grow
flex-grow
プロパティは、アイテムが主軸方向に伸長する倍率を定めます。この値は、同じフレックス・ボックスの空間を共有しているアイテム同士の相関関係を表します。
flex-grow
の値は、整数または小数点を含む数値で示します。これが0
の場合、アイテムはコンテナに余白があっても伸長しません。逆に1
やそれ以上の数値が指定してあってもコンテナの行に余白がない場合は機能しません。
この機能によって計算されるアイテムの寸法は固定値ではないため、例えflex-grow
の値が同じであっても、別のフレックス・ボックスに属するアイテムの寸法とは一致しません。
.item {
flex-grow: 1;
}
flex-shrink
flex-shrink
プロパティは、アイテムが主軸方向に収縮する倍率を定めます。この値は、同じフレックス・ボックスの空間を共有しているアイテム同士の相関関係を表します。
flex-shrink
の値は、整数または小数点を含む数値で示します。これが0
の場合、アイテムは基準となる寸法を尊重して収縮しません。また、コンテナの主軸方向に十分な余白がある場合も、収縮する必要がないので効果が現れません。
基本的な動作は、flex-shrink
の値が大きくなるほど収縮の倍率が増えます。例えば、同じ条件のアイテムに2
と4
を指定した場合は、4
の方が多く寸法を減少させます。
.item {
flex-shrink: 1;
}
flex-basis
flex-basis
プロパティは、アイテムの主軸方向に対する寸法の基準です。ここで指定された基準は、flex-grow
やflex-shrink
を計算する祭に利用されます。
flex-basis
の値は、あくまでアイテムの理想的な寸法です。実際に画面に表示される大きさは、コンテナのサイズ、アイテムの数、他のプロパティの値などによって変動し、最終的にはできるだけ指定された寸法に近い形で表示しようとします。
アイテムはflex-basis
とwidth
の両方が指定されていた場合、flex-basis
を優先しますが、その値がauto
であった場合はwidth
の値も参考にします。
.item {
flex-basis: 100px;
}
flex
flex
プロパティは、flex-grow
、flex-shrink
、flex-basis
の値をまとめて指定するショートハンド・プロパティです。全ての値を並べて記述する方法と、キーワードによる一括操作が行えます。
flex
を使用する場合は、値の順番に気を配る必要があります。基本的には、先に示したリンクの順番通りですが、値を省略した場合に適用される初期値も理解しておく必要があります。
フレックス・アイテムを伸縮させるために一番手軽な値としてflex: 1;
が使われますが、この値が何を意味しているのか、事前にflex
の解説を読んで把握しておきましょう。
.item {
flex: 1 0 100px;
}
align-self
align-self
プロパティは、コンテナの交差軸に余白がある場合に、アイテムをどこに寄せるのかを個別で指定します。これはalign-item
プロパティと同じ機能ですが、align-self
はアイテム自身に付加して、個別指定を行う場合に有効です。
コンテナ側にalign-item
が指定されている場合は、これを上書きします。また、コンテナの交差軸に十分な余白がなければ効果が現れません。
.item {
align-self: center;
}
order
order
プロパティは、コンテナの中に配置されたアイテムの並び順を指定します。この機能は、HTMLのソースコード上で記述された順序とは関係なく、コンテンツの配置を視覚的に変更したい場合に有効です。
order
を使用する場合は、並び順を変えないアイテムにも同様にプロパティを付加しておいた方が安全です。order
の初期値は0
であるため、このプロパティを指定したプロパティの前に割り込むためです。
以下の例は、5つ並べたアイテムの先頭に指定したorder
の値を変えていった場合の挙動です。HTMLのソースコードを変えなくとも、このように画面上の位置を動かすことができます。
.item {
order: 3;
}
まとめ
以上でフレックス・ボックスの解説は終わりです。上記で示した内容を理解すれば、フレックス・ボックスを思い通りに使いこなせるようになります。まずは個別のプロパティを暗記するよりも先に、コンテナとアイテムの関係性、主軸と交差軸の概念、先頭と末尾などの用語を把握しましょう。
プロパティを指定したのに効かない、期待した通りに画面に表示されないといった問題の多くは、そこで使われている言葉を理解することで解決します。分からなくなったら、もう一度このページへ戻って来て内容を確認してみましょう。
これ以降の作業は、実際に手を動かして色々なパターンのフレックス・ボックスを作成してみることです。各プロパティのページにサンプルを掲載しているので参考にして下さい。
CSSリファレンス一覧
-
CSSって何?初心者が最初に学ぶべき基礎知識
初めてCSSに触れる方はこちらから読み進めて下さい。CSSの役割やブラウザとの関係など、初心者にも分かりやすいように基礎知識を解説します。
入門編 -
CSSの書き方を詳しく解説!基本的な型とルールを覚えよう
CSSの書き方には一定の法則があるので、慣れてしまえば迷うことはないでしょう。まずは基本的な文法をマスターしましょう。
初級編 -
CSSの特徴をしっかりと把握しよう
CSSにはいくつかの特徴があります。これらを早いうちに理解しておくと、ウェブ制作の作業効率が格段に上がります。
初級編 -
CSSファイルの作り方
CSSファイルは誰でも簡単に作成できます。特別な技術やソフトウェアは必要ありません。
初級編 -
CSSセレクタの一覧表
スタイルの適用対象となる要素を選択するセレクタの一覧表です。詳しい書き方やサンプルコードを掲載しています。
学習編 -
CSSで使える単位の一覧表
プロパティの指定に用いる単位の解説です。CSSで使用できる単位の一覧表を掲載しています。
学習編 -
ボックス・モデルの完全解説
CSSの基礎が固まってきたらボックス・モデルについて学びましょう。これを理解するとCSSの操作が格段にやりやすくなります。
中級編 -
ブロックレベルとインラインレベルを理解する
CSSのブロックレベルとインラインレベルの特性について解説します。これらの扱いはHTMLからボックス・モデルに引き継がれました。
中級編 -
CSSの余白を表すmarginとpaddingを正しく理解する
要素の余白を表すmarginとpaddingについて正しい知識を身に着けましょう。
中級編 -
idとclassを上手く使い分ける
idセレクタとclassセレクタの使い分け方を詳しく解説します。
中級編 -
全称セレクタ(ユニバーサル・セレクタ)の解説
全ての要素のプロパティを一括で操作する全称セレクタについて解説します。
中級編 -
リストのデザインをマスターする
リストのデザインに関するCSSのテクニックを多数紹介します。入れ子、多段式、横並びを全て解決します。
応用編 -
フレックス・ボックスを理解する
横並びのレイアウトやレスポンシブデザインに対応するフレックス・ボックス(Flexible Box)について解説します。
応用編 -
グリッド・レイアウトを理解する
複数の行と列を作成して多次元のレイアウトを行うグリッド・レイアウトについて解説します。
応用編