目次
Flexboxについて
FlexboxとはCSS3から導入されたレイアウトに関する機能です。Flexboxを利用することで行あるいは列の1次元レイアウトを簡単に実現できます。
Flexboxの適用範囲であるレイアウト全体はFlexコンテナ、Flexboxが適用される要素はFlexアイテムと呼ばれています。1
つまり、Flexコンテナの中にFlexアイテムが並ぶイメージです。
Flexアイテムが並ぶ方向を主軸、主軸に対する垂直方向を交差軸と呼びます。
Flexboxの作り方
- Flexboxを適用する要素(Flexアイテム)の集合を作成する
- Flexアイテムの集合を親要素(Flexコンテナ)で囲む
- Flexコンテナに対して『display: flex』を適用する
具体的なコードは以下の通りです。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 150px;
height: 150px;
border: dotted;
}
.item1 {
background-color: lightblue;
}
.item2 {
background-color: greenyellow;
}
.item3 {
background-color: lightcoral;
}
See the Pen
flexbox-simple by Toshiharu Nishina (@nishina555)
on CodePen.
Flexアイテムの配置方向の決め方
Flexアイテムの配置方向はflex-direction
プロパティで制御します。
flex-direction
で指定できる値と意味の対応は以下の通りです。
値 | 意味 |
---|---|
row | 左から右(初期値) |
row-reverse | 左から右 |
column | 上から下 |
column-reverse | 下から上 |
たとえばflex-direction: row
の場合、主軸は水平方向、交差軸は垂直方向となります。
Flexアイテムの配置ルールの決め方
justify-content
とalign-items
を利用することでFlexコンテナに存在する各Flexアイテムの配置を一括で制御できます。
justify-content
は主軸に関する、align-items
は交差軸に関する配置を制御します。
justify-content
で指定できる値と意味の対応は以下の通りです。
値 | 意味 |
---|---|
flex-start | 先頭よせ(初期値) |
flex-end | 末尾よせ |
center | 中央よせ |
space-between | 両端にアイテムを配置し、アイテムを均等に配置 |
space-around | 両端は半分の間隔をあけ、アイテムを均等に配置 |
space-evenly | 両端も同じ間隔をあけ、アイテムを均等に配置 |
align-items
で指定できる値と意味の対応は以下の通りです。
値 | 意味 |
---|---|
stretch | コンテナあるいは最長アイテムの高さまで伸張(初期値) |
flex-start | 先頭よせ |
flex-end | 末尾よせ |
center | 中央よせ |
以下はjustify-content: space-between; align-items: center;
を組み合わせた例です。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 150px;
height: 150px;
border: dotted;
justify-content: space-between;
align-items: center;
}
.item1 {
background-color: lightblue;
}
.item2 {
background-color: greenyellow;
}
.item3 {
background-color: lightcoral;
}
See the Pen
flexbox-spece-between-center by Toshiharu Nishina (@nishina555)
on CodePen.
Flexアイテムの折り返し方法
Flexアイテムの折り返しはflex-wrap
プロパティで制御します。
Flexコンテナの領域からFlexアイテムがはみ出る可能性のある場合は、flex-wrap
を活用します。
flex-wrap
で指定できる値と意味の対応は以下の通りです。
値 | 意味 |
---|---|
nowrap | 折り返さない(初期値) |
wrap | 折り返す |
wrap-reverse | 逆順で折り返す |
以下はjustify-content: space-between; flex-wrap: wrap;
を組み合わせた例です。
<div class="container">
<div class="item lightblue">item</div>
<div class="item greenyellow">item</div>
<div class="item lightcoral">item</div>
<div class="item lightyellow">item</div>
</div>
.container {
display: flex;
width: 150px;
height: 150px;
border: dotted;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
width: 60px;
height: 60px;
}
.lightblue {
background-color: lightblue;
}
.greenyellow {
background-color: greenyellow;
}
.lightcoral {
background-color: lightcoral;
}
.lightyellow {
background-color: lightyellow;
}
See the Pen
flexbox-spece-between-center-wrap by Toshiharu Nishina (@nishina555)
on CodePen.
flex-flowプロパティについて
flex-flow
はflex-direction
とflex-wrap
の一括指定プロパティです。flex-direction
、flex-wrap
の順で指定します。
たとえばflex-flow: row wrap;
はflex-direction: row; flex-wrap: wrap;
と等価です。
各Flexアイテムのサイズを制御する方法
flex-grow
, flex-shrink
, flex-basis
を利用することで各Flexアイテムのサイズを制御できます。
flex-grow
, flex-shrink
, flex-basis
は、Flexコンテナ内に余った配置領域の再分配や、Flexコンテナからはみ出してしまった領域の縮小をします。
flex-basis
は伸縮する際の基準値です。0
、auto
、ピクセルなどが指定できます。初期値はauto
です。
flex-grow
には数値が設定できます。数値の比率に応じて余った領域の再分配が行われます。初期値は0です。
flex-shrink
には数値が設定できます。数値の比率に応じてアイテムの縮小が行われます。初期値は1です。
flexプロパティについて
flex
はflex-grow
, flex-shrink
, flex-basis
の一括指定プロパティです。flex-grow
, flex-shrink
, flex-basis
の順で指定します。
flex: 0 1 auto;
はflex-grow: 0; flex-shrink: 1; flex-basis: auto;
と等価です。
flex-grow
, flex-shrink
, flex-basis
は単体で利用されるケースは少ないです。ですので、Flexアイテム単体のサイズを制御する際はflex
を利用するケースがほとんどです。
よく利用される設定はflex
の値として定義されています。定義済みの値と意味の対応は以下の通りです。
値 | 意味 |
---|---|
initial | flex: 0 1 auto |
auto | flex 1 1 auto |
none | flex: 0 0 auto |
1 | flex: 1 1 0 |
特にflex: 1
は可変長Flexアイテムを作成する際によく利用されます。
flex-growの具体例
以下のようにFlexコンテナに余白のあるレイアウトがあったとします。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
}
.item1 {
background-color: lightblue;
width: 40px;
height: 40px;
}
.item2 {
background-color: greenyellow;
width: 40px;
height: 40px;
}
.item3 {
background-color: lightcoral;
width: 40px;
height: 40px;
}
See the Pen
flex-grow-before by Toshiharu Nishina (@nishina555)
on CodePen.
以下では、上記のコードに対してflex-grow
を適用した結果について紹介します。
すべてのFlexアイテムのflex-growの値が同じ場合
Flexコンテナの余白が均等に各Flexアイテムに振り分けられます。具体例は以下の通りです。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
}
.item1 {
background-color: lightblue;
width: 40px;
height: 40px;
flex-grow: 1;
}
.item2 {
background-color: greenyellow;
width: 40px;
height: 40px;
flex-grow: 1;
}
.item3 {
background-color: lightcoral;
width: 40px;
height: 40px;
flex-grow: 1;
}
See the Pen
flex-grow-after-equal by Toshiharu Nishina (@nishina555)
on CodePen.
各Flexアイテムで設定されているflex-growの値が異なる場合
flex-grow
の値の比率に応じてFlexコンテナの余白が振り分けられます。つまり、flex-grow
の値が大きいFlexアイテムほど幅が広くなります。
具体例は以下の通りです。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
}
.item1 {
background-color: lightblue;
width: 40px;
height: 40px;
flex-grow: 5;
}
.item2 {
background-color: greenyellow;
width: 40px;
height: 40px;
flex-grow: 3;
}
.item3 {
background-color: lightcoral;
width: 40px;
height: 40px;
flex-grow: 1;
}
See the Pen
flex-grow-after-differernt by Toshiharu Nishina (@nishina555)
on CodePen.
特定のFlexアイテムにのみflex-growが適用されている場合
flex-grow
のデフォルト値は0です。flex-grow: 0
はFlexアイテムが伸張しないことを意味します。
ですので、特定のFlexアイテムにのみflex-grow
が適用されている場合は当該アイテムにFlexレイアウトの余白がすべて振り分けられます。
具体例は以下の通りです。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
}
.item1 {
background-color: lightblue;
width: 40px;
height: 40px;
flex-grow: 1;
}
.item2 {
background-color: greenyellow;
width: 40px;
height: 40px;
}
.item3 {
background-color: lightcoral;
width: 40px;
height: 40px;
}
See the Pen
flex-grow-after-only by Toshiharu Nishina (@nishina555)
on CodePen.
flex-shrinkの具体例
以下のようにFlexアイテムがFlexコンテナからはみ出したレイアウトがあったとします。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
align-items: flex-start;
}
.item1 {
background-color: lightblue;
width: 100px;
height: 100px;
flex-shrink: 0; /* デフォルトは1なので明示的に0を指定 */
}
.item2 {
background-color: greenyellow;
width: 100px;
height: 100px;
flex-shrink: 0; /* デフォルトは1なので明示的に0を指定 */
}
.item3 {
background-color: lightcoral;
width: 100px;
height: 100px;
flex-shrink: 0; /* デフォルトは1なので明示的に0を指定 */
}
See the Pen
flex-shrink-before by Toshiharu Nishina (@nishina555)
on CodePen.
以下では、上記のコードに対してflex-shrink
を適用した結果について紹介します。
各Flexアイテムで設定されているflex-shrinkの値が異なる場合
flex-shrink
の値の比率に応じてFlexアイテムが縮小します。つまり、flex-shrink
の値が大きいFlexアイテムほど幅が狭くなります。
具体例は以下の通りです。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
border: dotted;
align-items: flex-start;
}
.item1 {
background-color: lightblue;
width: 100px;
height: 100px;
flex-shrink: 1; /* デフォルトは1なので指定しなくてもよい */
}
.item2 {
background-color: greenyellow;
width: 100px;
height: 100px;
flex-shrink: 1; /* デフォルトは1なので指定しなくてもよい */
}
.item3 {
background-color: lightcoral;
width: 100px;
height: 100px;
flex-shrink: 4;
}
See the Pen
flex-shrink-after-different by Toshiharu Nishina (@nishina555)
on CodePen.
覚えておくとよいFlexbox内の要素の特性
インライン要素も横幅・高さの指定が可能
display: flex
配下において要素はブロックレベル要素のように動作します。2
ですので、インライン要素で定義されたFlexコンテナ・Flexアイテムも横幅や高さの指定ができます。
<span class="container">
<span class="item">item</span>
</span>
.container {
display: flex;
width: 200px;
height: 200px;
background: lightgreen;
}
.item {
width: 150px;
height: 100px;
background: lightblue;
}
See the Pen
flexbox-inline by Toshiharu Nishina (@nishina555)
on CodePen.
要素のデフォルトの幅はコンテンツが収まるサイズ
通常ですと、幅の指定がないブロックレベル要素は親要素の幅と同じになります。
<div class="container">
<div class="item">item</div>
</div>
.container {
width: 200px;
background: lightgreen;
}
.item {
background: lightblue;
}
See the Pen
Untitled by Toshiharu Nishina (@nishina555)
on CodePen.
しかしFlexbox配下では、ブロックレベル要素のデフォルトの幅はインライン要素のようにコンテンツが収まるサイズとなります。
<div class="container">
<div class="item">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 100px;
background: lightgreen;
}
.item {
background: lightblue;
}
See the Pen
flexbox-block by Toshiharu Nishina (@nishina555)
on CodePen.
『text-align: center』でコンテンツの中央寄せはできない
Flexアイテム内のコンテンツを中央寄せする場合、text-align: center
は効きません。
<span class="item">item</span>
.item {
display: flex;
width: 200px;
height: 100px;
background: lightgreen;
text-align: center; /* 効かない */
}
See the Pen
flxbox-inline-text-align by Toshiharu Nishina (@nishina555)
on CodePen.
Flexアイテムのコンテンツの中央寄せしたい場合はjustify-content: center
を利用します。
<span class="item">item</span>
.item {
display: flex;
width: 200px;
height: 100px;
background: lightgreen;
justify-content: center; /* 効く */
}
See the Pen
flxbox-inline-justify-content-center by Toshiharu Nishina (@nishina555)
on CodePen.
参考: autoのmarginによる中央・上下左右寄せはできる
Flexbox配下においてtext-aling: center
によるコンテンツの中央寄せはできませんが、margin: 0 auto
による要素の中央寄せはできます。
<div class="container">
<div class="item">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
background: lightgreen;
}
.item {
width: 150px;
height: 100px;
background: lightblue;
margin: 0 auto;
}
See the Pen
flexbox-margin-zero-auto by Toshiharu Nishina (@nishina555)
on CodePen.
同様に上下左右寄せもできます。以下はmargin-bottom: auto
を利用した上寄せの例です。
<div class="container">
<div class="item1">item</div>
<div class="item2">item</div>
<div class="item3">item</div>
</div>
.container {
display: flex;
width: 200px;
height: 200px;
background: lightgreen;
}
.item1 {
width: 50px;
background: lightblue;
border: dotted;
margin-bottom: auto;
}
.item2 {
width: 50px;
background: lightblue;
border: dotted;
}
.item3 {
width: 50px;
background: lightblue;
border: dotted;
}
See the Pen
flexbox-margin-bottom-auto by Toshiharu Nishina (@nishina555)
on CodePen.
なお、上記の結果をみてわかる通り、align-items: stretch
が適用されていても、align-items
の軸に対してautoのmarginで要素を寄せると、要素の幅はコンテンツが収まる大きさに縮まります。
Flexboxの利用例
横並びのカードアイテム
ランディングページでよく見る『3つのカード状のアイテムを横に並べる』というレイアウトはFlexboxで実現できます。
具体的なコードは以下の通りです。
<div class="container">
<div class="item lightblue">item</div>
<div class="item greenyellow">item</div>
<div class="item lightcoral">item</div>
</div>
.container {
display: flex;
justify-content: space-between;
border: dotted;
}
.item {
width: 200px;
height: 250px;
}
.lightblue {
background-color: lightblue;
}
.greenyellow {
background-color: greenyellow;
}
.lightcoral {
background-color: lightcoral;
}
.lightyellow {
background-color: lightyellow;
}
See the Pen
flexbox-card-simple by Toshiharu Nishina (@nishina555)
on CodePen.
上記のコードはjustify-content: space-between;
を利用していますが、space-around
やcenter
でも実装可能です。
類似コードはCSS Flexboxによる中央寄せ横並びレイアウトの実装3パターン比較でも紹介しています。
ページネーション
ページネーションをはじめとした『固定長のアイテムを指定された間隔で横に並べる』というレイアウトは、たとえばjustify-content: flex-start;
とmargin-right
を組み合わせることで実現できます。
具体例は以下の通りです。
<div class="container">
<div class="item lightblue">item</div>
<div class="item greenyellow">item</div>
<div class="item lightcoral">item</div>
<div class="item lightyellow">item</div>
</div>
.container {
display: flex;
justify-content: flex-start; /* 初期値なので指定しなくてもよい */
}
.item {
width: 60px;
height: 60px;
}
.item:not(:last-child){
margin-right: 10px; /* 最後のアイテムのマージンは不要 */
}
.lightblue {
background-color: lightblue;
}
.greenyellow {
background-color: greenyellow;
}
.lightcoral {
background-color: lightcoral;
}
.lightyellow {
background-color: lightyellow;
}
See the Pen
flexbox-pagination-simple by Toshiharu Nishina (@nishina555)
on CodePen.
PCの場合は横並び、スマートフォンの場合は縦並びにする
メディアクエリとflex-direction
を利用することで画面幅に応じてアイテムの配置方向を変更できます。
具体例は以下の通りです。
<div class="container">
<div class="item lightblue">item</div>
<div class="item greenyellow">item</div>
<div class="item lightcoral">item</div>
</div>
.container {
display: flex;
justify-content: space-between;
border: dotted;
}
.item {
width: 200px;
height: 250px;
}
.lightblue {
background-color: lightblue;
}
.greenyellow {
background-color: greenyellow;
}
.lightcoral {
background-color: lightcoral;
}
.lightyellow {
background-color: lightyellow;
}
@media screen and (max-width: 599px) {
/* 600px未満の場合に適用される */
.container {
flex-direction: column; /* flexの向きを垂直方向に変更。主軸・交差軸が入れ替わる */
align-items: center; /* 交差軸を中心揃えにする(= 中央寄せになる) */
width: 100%; /* 画面の幅に応じて親要素の幅が動的になるようにする */
}
.item:not(:last-child) {
margin-bottom: 10px;
}
}
See the Pen
flexbox-responsive-simple by Toshiharu Nishina (@nishina555)
on CodePen.
上記の方法以外でもレイアウトの切り替えは可能です。
レイアウトを切り替える手法の詳細は横並びレイアウトを縦並びに変更するCSS Flexbox実装3パターンまとめをご覧になってください。
2カラムレイアウトを作成する
Webサイトでよく見る『可変長のメインカラムと固定長のサイドバー』というレイアウトはflex: 1
を利用することで実現できます。具体例は以下の通りです。
<div class="container">
<div class="main">main</div>
<div class="side">side</div>
</div>
.container {
display: flex;
border: dotted;
}
.main {
flex: 1; /* コンテナの余り領域に応じて伸縮する */
background-color: lightblue;
min-width: 300px; /* 最低300pxは幅を確保する */
}
.side {
width: 300px;
background-color: greenyellow;
}
See the Pen
flexbox-two-columns-simple by Toshiharu Nishina (@nishina555)
on CodePen.
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!