flexbox とはなんぞや?

基本的には display プロパティによる指定の一種

CSS プロパティ display は表示方式をコントロールする。例えば要素をブロックとして表示するという意味で display: block と指定したり、要素をテーブルとして表示することを指定する display: table といった指定が出来る。

flexbox とはこの displayflexを指定した要素を指す。

そして display: flex としたブロックでは専用に用意された flex-xxxxxといったスタイル指定により柔軟なレイアウトの指定が出来るようになる。

MDN の「柔軟なレイアウト」解説

基本構造

flexbox はそのコンテナと子要素からなり、それぞれを flex コンテナ、flex アイテムと呼称することが多いが、flex アイテムがまた flex コンテナとなる事もある。

<div style="display: flex;"><!-- flex コンテナ -->
	<div>flexアイテム1</div>
	<div>flexアイテム2</div>
	<div>flexアイテム3</div>
</div>

ここでは基本的に flex コンテナと、その中に入った複数の flex アイテム、という単純な構成で flex-xxxx スタイル指定について解説する。

Flexbox コンテナ側に設定するスタイル

基本

デフォルト

コンテナとなるブロックに display: flex; を指定しただけ。右に溢れる事が分かる様にたくさんの子要素を入れている。

<div style="display: flex;">
	<div>Item01</div>
	<div>Item02</div>
	<div>Item03</div>
	...
</div>
Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12
Item13
Item14
Item15
Item16

デフォルト + ネストした div

flex コンテナ直下の div の中にさらに div を並べたケース。どうやら flex の特徴が出るのはコンテナ直下のブロックのみの模様。

Item1
Item2-1
Item2-2
Item2-3
Item3

子要素を並べる方向を指定する - flex-direction

例:

<div style="
	display: flex;
	flex-direction: row;
">
	<div>Item1</div>
	<div>Item2</div>
	...
</div>

row(デフォルト)

Item1
Item2
Item3
Item4

row-reverse

Item1
Item2
Item3
Item4

column

Item1
Item2
Item3
Item4

column-reverse

Item1
Item2
Item3
Item4

横揃えを指定する - justify-content

例:

<div style="
	display: flex;
	justify-content: flex-tart;
">
	<div>Item1</div>
	<div>Item2</div>
	...
</div>

flex-start(デフォルト)

Item1
Item2
Item3
Item4

flex-end

Item1
Item2
Item3
Item4

center

Item1
Item2
Item3
Item4

space-between

Item1
Item2
Item3
Item4

space-around

Item1
Item2
Item3
Item4

縦方向の制御指定 - align-items

例:

<div style="
	display: flex;
	align-items: stretch;
	height: 6rem;
">
	<div>Item1</div>
	<div>Item2</div>
	...
</div>

stretch(デフォルト)

Item1
Item2
Item3
Item4

flex-start

Item1
Item2
Item3
Item4

flex-end

Item1
Item2
Item3
Item4

center

Item1
Item2
Item3
Item4

baseline

分かりにくいがテキストのベースラインを合わせる。この例では一番縦長の item3 のボックスが上寄せになりその中のテキストに他のテキストがそろえられる感じ。

Item1
Item2
Item3
Item4

折り返しの指定 - flex-wrap

例:

<div style="
	display: flex;
	flex-wrap: nowrap;
">
	<div>Item01</div>
	<div>Item02</div>
	...
</div>
	

nowrap(デフォルト)

折り返し無し

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12
Item13
Item14
Item15
Item16

wrap

親要素(Flexbox)に合わせて折り返す。

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12
Item13
Item14
Item15
Item16

wrap-reverse

親要素(Flexbox)に合わせて上に折り返す(イマイチ用途が思い浮かばない)

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12
Item13
Item14
Item15
Item16

複数行の時の縦方向の揃え - align-content

flex-wrap: wrap; に設定されていることが前提。

基本的には親要素である Flexbox の上下には溢れる(ウィンドウの横幅を狭めてみると確認出来る)。

例:

<div style="
	display: flex;
	flex-wrap: wrap;
	height: 10rem;
	width: 50%;
	align-content: stretch;
">
	<div>Item01</div>
	<div>Item02</div>
	...
</div>
	

stretch(デフォルト)

子要素ボックスを建てに引き延ばして埋める

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

flex-start

子要素ボックスのサイズは変えずに上に寄せる

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

flex-end

子要素ボックスのサイズは変えずに上に寄せる

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

center

縦方向のセンターに寄せる

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

space-between

等間隔1

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

space-around

等間隔2

Item01
Item02
Item03
Item04
Item05
Item06
Item07
Item08
Item09
Item10
Item11
Item12

子要素側に設定できるスタイル

縦方向の制御 - align-self(align-itemsのflexアイテム版)

一通りの設定

auto
flex-start
flex-end
stretch
center
baseline
<div style="
		display: flex;
		height: 6rem;
	">
	<div style="align-self: auto;">auto</div>
	<div style="align-self: flex-start;">flex-start</div>
	<div style="align-self: flex-end;">flex-end</div>
	<div style="align-self: stretch;">stretch</div>
	<div style="align-self: center;">center</div>
	<div style="align-self: baseline;">baseline</div>
</div>
	

順番を入れ替える - order

order

子要素の方に order: 番号で指定することで順番を入れ替えることが出来る。表にしたときのソート機能に使えるかも?

Item01
Item02
Item03
Item04
Item05
Item06
<div style="
		display: flex;
		flex-wrap: wrap;
	">
	<div style="order: 6;">Item01</div>
	<div style="order: 1;">Item02</div>
	<div style="order: 5;">Item03</div>
	<div style="order: 2;">Item04</div>
	<div style="order: 4;">Item05</div>
	<div style="order: 3;">Item06</div>
</div>
	

同じ値はどうなるか

item02,04,05 の order を 2 にした。他は指定無し = デフォルトの 0 扱いのはず。

→ 同値は元の並び順が優先される模様

Item01
Item02
Item03
Item04
Item05
Item06

伸びる比率 - flex-grow

主軸方向(通常は横)に余ったスペース幅を各子要素の幅を按分でストレッチする指定。デフォルト値は 0。

0 は足し算しても 0 で按分できないのでストレッチされない。。

0
0
0
0

全てに 1 (あるいは同じ値)を与えるとそれぞれが同じサイズにストレッチされる

1
1
1
1
3
3
3
3
<div style="display: flex;">
	<div style="flex-grow: 3;">3</div>
	<div style="flex-grow: 3;">3</div>
	<div style="flex-grow: 3;">3</div>
	<div style="flex-grow: 3;">3</div>
</div>
	

最後のアイテムだけ 1 にする

0
0
0
1

按分なので 6 にしてもストレッチされる量は変わらない

0
0
0
6

1番目のブロックに 3 を指定すると、3:6 = 1:2 となり最後のブロックの半分の長さが振り分けられる。あくまで本来ならスペースになったサイズが按分されるという点に注意

3
0
0
6
01
02
03
04
05
06
07
08
09

1:3:5:7 = 1/16 : 3/16 : 5/16 : 7/16

1
3
5
7
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16

↑ 余った余白を按分するので、単に等分割した場合のサイズは参考にならない。

縮める比率 - flex-shrink

Flexbox に収まりきらない場合のフレックスアイテムの縮小係数。デフォルト値は 1。

収まりきっている場合は何の効果も発揮しない

111111
111111
111111
111111

溢れる場合でもブロックを縮められない場合はシュリンクしない

111111
111111
111111
111111

width:等でのサイズ指定の場合シュリンク(というかこの場合はストレッチか?)する

以下は子要素 width8rem だが、flexbox は 24rem で子要素が溢れるはずだが全ての子要素にflex-shrink: 1をセットしているので同比率でシュリンクしている

1
1
1
1
1
1
1
1

↑各子要素の本来のサイズ

最後の子要素を 2 にする。1/2 ということだろうか?

1
1
1
2

最後の子要素を 3 にする。1/3 ということだろうか?

1
1
1
3

最後の子要素を 4 にする。1/4 ということだろうか?

1
1
1
4
<div style="
		display: flex;
		width: 24rem;
	">
	<div style="flex-shrink: 1;width: 8rem;">1</div>
	<div style="flex-shrink: 1;width: 8rem;">1</div>
	<div style="flex-shrink: 1;width: 8rem;">1</div>
	<div style="flex-shrink: 4;width: 8rem;">4</div>
</div>
	

イマイチシュリンクの計算式がよく分からない。。。

幅のベースサイズ - flex-basis

前述のflex-shrinkの検証のためには子要素の幅に width を使ったが、flex アイテムには専用の横幅指定スタイルがある。それがflex-basis

auto

デフォルト値 auto

auto
auto
auto
auto
<div style="display: flex;">
	<div style="flex-basis: auto;">auto</div>
	<div style="flex-basis: auto;">auto</div>
	<div style="flex-basis: auto;">auto</div>
	<div style="flex-basis: auto;">auto</div>
</div>
	

サイズ指定

8rem
8rem
8rem
8rem
64pt
64pt
64pt
64pt
200px
200px
200px
200px

パーセント指定

10%
10%
10%
10%
20%
20%
20%
20%
50%
50%
50%
50%

flex - flex-grow,flex-shrink,flex-basis を一度に設定する

普通はこの方法でflex-grow,flex-shrink,flex-basis を一度に設定する。

よくあるパターン

1 1 auto
1 1 auto
1 1 auto
1 1 auto
<div style="display: flex;">
	<div style="flex: 1 1 auto;"><code>1 1 auto</code></div>
	<div style="flex: 1 1 auto;"><code>1 1 auto</code></div>
	<div style="flex: 1 1 auto;"><code>1 1 auto</code></div>
	<div style="flex: 1 1 auto;"><code>1 1 auto</code></div>
</div>
	
0 1 auto
0 1 auto
0 1 auto
0 1 auto
0 1 20%
0 1 20%
0 1 20%
0 1 20%

まとめとしてよくあるプロフィールレイアウトを実現する

ヘッダとか?
サムネ
ホゲホゲ所属
ハナモゲラ担当
名前
詳細コンテンツ、あるいはフッター
<div style="
			display: flex;
			flex-direction: column
			">
	<div style="display: flex; justify-content: center">
	<!-- ヘッダー -->
		<div>ヘッダとか?</div>
	</div>
	<div style="display: flex;
			flex-direction: row
			">
		<!-- サムネ と基本プロパティー行-->
		<div style="flex: 0 1 64pt">サムネ</div>
		<div style="flex: 1 1 auto">
			<!-- 基本プロパティー-->
			<div style="text-align: left;">ホゲホゲ所属</div>
			<div style="text-align: left;">ハナモゲラ担当</div>
			<div style="text-align: left;">名前</div>
		</div>
	</div>
	<div style="display: flex;"">
	<div style="flex: 1 1 auto;text-align: left;">
		詳細コンテンツ、あるいはフッター
	</div>
		
	</div>
</div>