備忘録的プログラミングリファレンス

display: flex; の使い方

 display: flex; を用いたレイアウトの作成とその調整方法についての解説です。
 この display: flex; は、フレックスボックス(FlexBox)という画像やコンテンツを横並びにすることができる CSS によるレイアウトモードです。

display: flex;
flex_item01
flex_item02
flex_item03

 画像やコンテンツはデフォルトでは縦に順次並びますが、display: flex; はそれらを横並びにすることができます。
 さらに、表示デバイスの大きさによって並び方を調整することや横スクロールを追加することもできます。

 横並びにするには float プロパティを使用する方法もあります。レスポンシブレイアウトには display: flex; の方が向いています。

配置の基本

 display: flex; では以下のような表示基準が設けられています。

 ━━━→main axis(主軸)
┃
┃
┃
↓
cross axis
(交差軸)

 デフォルトでは横方向が main axis(主軸)で縦方向が cross axis(交差軸)になります。フレックスボックスのモードでは、中のコンテンツは横並びになります。

デフォルトのフッレクスボックス
flex_item01
flex_item02
flex_item03

 flex-direction プロパティによって main axis(主軸)と cross axis(交差軸)を入れ替えることができます。入れ替えることでコンテンツの並びを縦方向にすることもできます。

 以下は flex-direction: column; と指定しています。

flex-direction: column;
flex_item01
flex_item02
flex_item03

display: flex;による効果

 display: flex; のみの設定ではフレックスアイテム(子エレメント)は横に並ぶだけでが、先に display: flex; を指定していない場合はどのように表示されるかをみてみます。

 例えば、以下のようにcontenaエレメントが3つのflex_item01flex_item02flex_item02 エレメントを包括しているとします。

<div class="contena">
  <div class="item a"> flex_item01 </div>
  <div class="item b"> flex_item02 </div>
  <div class="item c"> flex_item02 </div>
</div>

<style>
.item{
	border:1px solid gray;
}
</style>

border は分かりやすく表示されるように設定してあります。

 display: flex; を設定していない場合は以下のように表示されます。

 display: flex; を設定していない場合は上の例のように表示されます。

display: flex; の設定

 次に display: flex; を設定してみます。

.contena {
	display: flex;

	width: 80%;
	border: 1px solid gray;
}

widthborder は分かりやすく表示されるように設定してあります。

 以下のように横並びで表示されます。display: flex; によって上記の縦に並んだアイテムを横に並べることができます。

 contenaエレメントをフレックスコンテナ、子エレメントであるflex_item01flex_item02flex_item02 エレメントをフレックスアイテムと呼びます。

 display: flex; はデフォルトで、 main axis(主軸)方向にフレックスアイテムは並びます。フレックスアイテムの幅はそれぞれのコンテンツ(内容)の大きさに合わせられます。

 display: flex; のみ設定ではフレックスアイテムは横に並ぶだけです。次はフレックスアイテムの配置を調整してみます。

折返し

 display: flex; によって横並びにしたアイテムを折り返しで表示したい場合があります。フレックスアイテムを折返し表示をするには、flex-wrap プロパティを使用します。

 display: flex; を設定しただけではフレックスアイテムは横に並ぶだけです。例えば以下のフレックスコンテナを右下のリサイズボタンで変更してみましょう。

flex_item01
flex_item02
flex_item03

 フレックスアイテムが並びきらない幅にすると、並びきらない部分は表示されません。

 常にアイテムを全て表示できるようにしたい場合があります。その場合には flex-wrap プロパティでアイテムの折返しを指定します。

.contena {
	display: flex;
	flex-wrap: wrap;

	border: 1px solid gray;
	overflow: hidden;
	resize: horizontal;
	width: 330px;
}

borderoverflowresizewidth プロパティは分かりやすく表示されるように設定しています。

 以下の例は flex-wrap: wrap; と並びきらないアイテムは折り返して表示するように指定しています。右下のリサイズボタンで親エレメントの大きさを変更してみてください。

 以下のように横並びで表示されます。display: flex; によって上記の縦に並んだアイテムを横に並べることができます。

 幅を変更すると、高さを変更しながらフレックスアイテムが全て表示されるように表示されます。

レスポンシブ web デザインへの対応

 表示幅ごとに、コンテンツを横に並べたり縦に並べたりできるためレスポンシブ web デザインに利用することができます。

 例えば以下のようなコンテンツの場合、幅が 620px より大きい場合は横に並べて表示しますが、それより小さければコンテンツを縦に並べて表示します。

 上記の例のコードは以下のようになります。

 フレックスコンテナには flex-wrap: wrap; を設定し、各アイテムはそのサイズを調整しています。

<style>
.contena {
	display: flex;
	flex-wrap: wrap;

	overflow: hidden;
	resize: horizontal;
	width:100%;
	border: 1px solid gray;
}

.item {
	width:280px;
	height:200px;
	margin:5px;
	border:1px solid gray;
}
</style>

<div class="contena" ">
  <div class="item" > flex_item01 </div>
  <div class="item" > flex_item02 </div>
</div>

borderoverflowresizewidth プロパティは分かりやすく表示されるように設定しています。

アイテムの大きさ

 フレックスアイテムの大きさの指定には widthheight の他に flex-basis プロパティがあります。

 flex-basis は主軸方向が横の時にはアイテムの幅、縦の時は高さを指定するプロパティです。width との違いは主軸方向を変更する flex-direction に対応しているか/否かの違いです。

 まずは、flex-basis プロパティでアイテムの幅を指定する方法からみてみます。

<style>
.item {
	flex-basis: 100px;

	border: 1px solid gray;
}

.contena {
	display: flex;

	flex-wrap: wrap;
	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

borderoverflowresizewidth プロパティは分かりやすく表示されるように設定しています。

 この設定は以下のように表示されます。

縦並びでの flex-basis プロパティ

 flex-basis プロパティは flex-direction で主軸方向を縦に変更するとアイテムの高さになります。
 幅は指定がなければデフォルの大きさになります。ここではアイテムの幅は親エレメントの大きさになります。

.contena {
	display: flex;
	flex-direction: column;
}

一定の大きさのフレックスアイテム

 フレックスアイテムの大きさが決まっており、横並びでも縦並びでもアイテムの大きさは同じで表示したい場合は widthheight プロパティを使用します。
 width プロパティならば縦並びでも横並びでも同じアイテム幅になります。width プロパティは flex-basis より優先されますので、 flex-basis を設定してあると縦方向に変更したときに高さが変わることに注意する必要があります。

<style>
.item {
	width: 100px;
	height: 100px;

	border: 1px solid gray;
}

.contena {
	display: flex;

	flex-wrap: wrap;
	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

borderoverflowresizewidth プロパティは分かりやすく表示されるように設定しています。

 主軸方向を flex-direction プロパティで縦に変更してもアイテムの width は幅の指定になります。

縦並びでの width
flex_item01
flex_item02
flex_item03

 フレックスアイテムごとに表示幅を変えるには、アイテムごとに幅を指定します。

アイテムどうしの間隔

 フレックスアイテムどうしの間隔を変更するには margin プロパティを使用します。

 アイテムどうしの間隔を作ることができます。

<style>
.contena {
	display: flex;

	flex-wrap: wrap;
	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

.item {
	width: 100px;
	height: 100px;
	margin: 10px;

	border: 1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

borderoverflowresizewidth プロパティは分かりやすく表示されるように設定しています。

 上の例は、アイテムの上下左右に 10px の margin を指定しています。そのためアイテム間には 20px の margin があります。

スクロール表示

 フレックスアイテムはスクロール表示させることができます。display: flex; を設定したフレックスコンテナに overflow-x を指定します。 ただし、フレックスアイテムの表示幅の合計がコンテナの幅より大きいときにスクロールは表示されます。

 スクロールを表示するには、フレックスアイテムには max-width プロパティを、アイテムには min-width プロパティを設定すると上手くいきます。

<style>
.contena{
	display: flex;
	max-width: 600px;
	overflow-x: auto;
	height: 230px;

	border:1px solid gray;
}

.item {
	min-width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

 アイテムの高さに合わせてコンテナの高さも調節する必要があります。

フレックスコンテナの親エレメント

 フレックスコンテナに <div> といった親エレメントを設定することでスクロール表示させることもできます。

 以下の例では over クラスが親エレメントになります。

 この方法なら、既存のフレックスコンテンツをスライドにし直すことがより簡易にできます。
 要点としては、display: flex; を設定したエレメントの幅をその親エレメント(ここでは over クラスのエレメント)よりも大きいときにスクロールバーが表示されます。

 ここでは」スクロールバーが表示されるように、フレックスコンテナには min-width を、その親エレメントには max-width を設定しています。

<style>
.over{
	max-width: 600px;
	overflow-x: auto;
}

.contena{
	display: flex;
	min-width: 800px;
	height: 230px;

	border: 1px solid gray;
}

.item {
	width: 200px;
	height: 200px;

	margin: 10px;

	border: 1px solid gray;
}
</style>

<div class="over">
	<div class="contena">
		<div class="item a" > flex_item01 </div>
		<div class="item b" > flex_item02 </div>
		<div class="item c" > flex_item03 </div>
	</div>
</div>

フレックスアイテムの配置位置

 フレックスアイテムの配置位置は、親エレメントの高さ(詳しくは交差軸)に対して上、真中、下を指定する align-items プロパティがあります。

<style>
.contena{
	display: flex;
	height: 250px;
	align-items: center;
	flex-wrap: wrap;

	border:1px solid gray;
}

.item {
	width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

  フレックスコンテナに align-items プロパティによって設定した配置位置は初期値です。後でアイテムごとに align-self によって個々に位置を指定することができます。

<style>
.contena{
	display: flex;
	width: 100%;
	height: 250px;
	align-items: center;
	flex-wrap: wrap;

	border:1px solid gray;
}

.contena .item {
	width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}

.contena .a {
	align-self: flex-start;
}

.contena .c {
	align-self: flex-end;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

フレックスアイテム全体の上下左右の位置の調整

 フレックスアイテム全体の配置位置を指定するプロパティに、align-contentjustify-contentがあります。

 align-content はフレックスコンテナの高さに対して上、真中、下の指定ができます。

<style>
.contena{
	display: flex;
	width: 100%;
	height: 250px;
	align-content: center;
	flex-wrap: wrap;

	border:1px solid gray;
}

.contena .item {
	width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>
	

 justify-content はフレックスコンテンツの幅に対しての左より、真中、右よりの指定ができます。

<style>
.contena{
	display: flex;
	width: 100%;
	height: 250px;
	justify-content: center;
	flex-wrap: wrap;

	border:1px solid gray;
}

.contena .item {
	width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>

 align-contentjustify-content を設定したフレックスアイテムで align-self プロパティ はブラウザによって機能しないようです。

<style>
.contena{
	display: flex;
	width: 100%;
	height: 250px;
	align-content: center;
	justify-content: center;
	flex-wrap: wrap;

	border:1px solid gray;
}

.contena .item {
	width: 200px;
	height: 200px;
	margin: 10px;

	border:1px solid gray;
}

.contena .a {
	align-self: flex-start;
}

.contena .c {
	align-self: flex-end;
}
</style>

<div class="contena">
	<div class="item a" > flex_item01 </div>
	<div class="item b" > flex_item02 </div>
	<div class="item c" > flex_item03 </div>
</div>