Flexboxを使うことによって、より簡単にCSSでレスポンシブなレイアウトが作れます。
要素の配置や、縦横の中央揃え、順番の変更などなど覚えておくとCSSが楽しくなりますし、より簡単で短いコードで実装できます。
*この記事はカナダのフルスタックエンジニア・デザイナーのWes Bosさんから許可を得て、FlexBoxのレッスン動画「What The FlexBox」の内容を日本語で紹介しています。
ここでは基礎のみを紹介していきますので、さらに詳しく学びたい人はWes Bosさんのコース(英語)をチェックしてみてください。*このコースは無料です。
コードと写真を載せているので、実際に手を動かしながら読んでみてくださ〜^ ^
目次
- FlexBox基礎まとめ【準備】
- flexとinline-flex
- flex-direction
- flex-wrap
- order
- justify-content
- align-items
- align-content
- align-self
- flex-grow / shrink / basis
- まとめ:FlexBoxは便利なので覚えておきましょう〜
FlexBox基礎まとめ【準備】
まずこれから例としてどんどん紹介していくので基盤となるHTML/CSSを準備します
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>FlexBox Practice</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box box7">7</div>
<div class="box box8">8</div>
<div class="box box9">9</div>
<div class="box box10">10</div>
</div>
</body>
</html>
CSS
.box {
color: white;
font-size: 70px;
text-align: center;
padding: 10px;
}
.box1 { background: #FDA403 }
.box2 { background: #11CBD7 }
.box3 { background: #C51350 }
.box4 { background: #61B292 }
.box5 { background: #F2855E }
.box6 { background: #6A65D8 }
.box7 { background: #46CDCF }
.box8 { background: #032A33 }
.box9 { background: #FDB44B }
.box10 { background: #0E9577 }
.container {
//ここにflexboxのコードなど入れていきます。
}
この状態での表示はこんな感じ
このコードを元に解説していきます。
flexとinline-flex
.container
に色々書いていく
*わかりやすいようにborderをかけます。
まずdisplay: flex;
を追加
.container {
border: 5px solid red;
display: flex;
}
すると
.containerにflexをかけることで横並びになり、中身の.boxがflex-itemになります。
display: inline-flex;
だと以下ようにinline-flexだとborderが中身の幅になります。
display: flex;
に戻して、.containerにheight: 100vh;
をかけると
これはデフォルトがstretchだから下まで伸びます。(*stretchについてはあとで解説します)
flex-direction
flex-direction: row;
がデフォルト
.containerにflex-direction: column;
をかけると以下のようになります。
ここでaxis(軸)について紹介
flexboxを使うにあたって、main-axis(メインの軸)とcross-axis(クロスの軸)について知っておく必要があります。
デフォルト(flex-direction: row;
)の時のmain-axisは左から右、cross-axisは上から下
flex-direction: column;
の時はmain-axisは上から下、cross-axisは左から右
flex-direction: row-reverse;
だとrowの逆
flex-direction: column-reverse;
だとcolumnの逆
後から出てきますのでわからないときはここに戻ってきてください〜
うまくいかない時はaxisがどの向きになっているか確認してみましょう
flex-wrap
flex-directionを削除して、.containerの中の.box(flex-item)にwidth: 300px;
をつけてみます。
すると、
300px × box10個で3000pxの幅が必要で開いているこの時のブラウザの幅は1000pxくらいではみ出るはずですが、はみ出てませんね。
ここで.containerにflex-wrap: wrap;
をかけてみます。
*デフォルトではnowrapになっています。
.boxの横幅300pxが適用され、横に.boxが入るスペースがなくなると続けて下に並んでいきます。
また、.boxの高さは.container(height: 100vh;
)に全部の.boxが収まるように決まります。
なのでブラウザの縦横を縮めると、、、
こんな感じで縮まります。
flex-wrap: wrap-reverse;
だと先ほどのcross-axisが逆になり、以下のような表示になります。
flex-wrap: wrap;
に戻して、.boxをwidth: 33.33333%;
にします。
*全体のbox-sizingをborder-boxにしないとちゃんと反映されません
右の余白がなくなりましたね。
ここで.containerにflex-direction: column;
をかけてみます。
すると、、、
box内の数字を見ればわかるかと思いますが、先ほどのmain-axisが上から下に変わり、heightが100vhなのでブラウザの高さにbox達が入らなくなるとwrapしてまた上からboxが並んでいます。
.containerをmin-height: 100vh;
に変更すると、
wrapする場所がなくなるので、boxがズラーっと下に並んでいきます。
boxとboxの間に隙間を開けたい時
全部元に戻します。
CSS
.container {
border: 5px solid red;
display: flex;
min-height: 100vh;
flex-wrap: wrap;
}
.box {
width: 33.33333%;
}
ここでもしmarginを使って隙間を開けたい時はcalcを使えばうまく隙間を作れます。
.box {
width: calc(33.33333% - 20px);
margin: 10px;
}
*左右のmarginが10pxなので-20px
order
以下のようにCSSを最初の状態に戻して.containerにflexをかけます。*htmlはそのまま
.box {
color: white;
font-size: 70px;
text-align: center;
padding: 10px;
}
.box1 { background: #FDA403 }
.box2 { background: #11CBD7 }
.box3 { background: #C51350 }
.box4 { background: #61B292 }
.box5 { background: #F2855E }
.box6 { background: #6A65D8 }
.box7 { background: #46CDCF }
.box8 { background: #032A33 }
.box9 { background: #FDB44B }
.box10 { background: #0E9577 }
.container {
display: flex;
}
こんな表示に戻ります。
.box3 { order: 1; }
を追加してみます。
すると、
.box3が一番端っこに移動しました。
なぜなら、.box(flex-item)のデフォルトのorderは0だからです。
.box5をorder: 2;
にすると、、、
box5が一番端っこに移動しました。
*box3のorder < box5のorderだから
.boxのorderを999とかにしておくと、番号の小さい順に並べれます。
orderはレスポンシブデザイン等に便利で、「スマホの時はこの要素とこの要素の順番を変えて欲しい」などの要望があった際に、orderを変えるだけで簡単に順番を変更できます。
そんな要望が頻繁にあるかどうかはさておきw
justify-content
またまたCSSを元に戻します。
.box {
color: white;
font-size: 70px;
text-align: center;
padding: 10px;
}
.box1 { background: #FDA403 }
.box2 { background: #11CBD7 }
.box3 { background: #C51350 }
.box4 { background: #61B292 }
.box5 { background: #F2855E }
.box6 { background: #6A65D8 }
.box7 { background: #46CDCF }
.box8 { background: #032A33 }
.box9 { background: #FDB44B }
.box10 { background: #0E9577 }
.container {
display: flex;
}
.containerにjustify-contentでいろいろつけていきます。
*デフォルトはjustify-content: flex-start;
これがデフォルト(justify-content: flex-start;
)
flex-end
center
space-between
*わかりやすいように.containerにborderをつけています。
space-around
space-evenly
こんな感じです。
ここで.containerにflex-direction: column;
をかけると、、、
boxとbox間のスペースがなくなってしまいました。
なぜなら、高さ(height)を設定していないからです。
そこで、.containerにmin-height: 100vh;
をつけてみます。
*これだけだとboxが大きすぎて100vhに収まらないのでスペースはできません。
なので、.boxをfont-size: 20px;
にしてboxの大きさを小さくします。
すると、、、
space-evenly
でスペースができていますね。
flex-start
にすると、
こんな感じでmain-axisの向きが上から下になるのでboxも上から下に並んでいきます。
ちなみにcenter
にすると
わかりにくいかもですが、縦の中央揃えになっています。
「justify-contentはmain-axisに沿ってレイアウトされる」って感じです。
align-items
justify-contentと違いalign-itemsはcross-axisに沿ってレイアウトされます。
CSSを最初の状態に戻して.containerにalign-items
をつけてみます。
.container {
display: flex;
border: 5px solid royalblue;
align-items: center;
}
*わかりやすいようにborderをつけています。
center
あれ・・・?何も変わってない・・・
高さを決めてないので変わりません。
.containerにheight: 100vh;
をつけてみると、、、
こんな感じで縦の中央揃えになります。
stretch(デフォルト)
align-items: stretch;
にすると
align-itemsをつけていない時と同じ状態になります。
flex-start
flex-end
baseline
align-items: baseline;
にすると、例の場合、box(flex-item)内の数字の底辺に合わせて並びます。
boxそれぞれのフォントサイズをバラバラにしてbaselineをつけてみます。
すると、、、
*赤い点線がbaselineです。
便利ですね〜^ ^
フォントサイズを戻して、.containerにflex-direction: column;
をつけてalign-items: center;
にしてみます。
すると、、、
*height: 100vh;
をmin-height: 100vh;
に変更しています。
flex-directionをcolumnにしたことで、main-axisは上から下に、cross-axisは右から左に変わります。
先ほど書いたようにalign-itemsはcross-axisに沿って反映されるので、横の中央揃えになります。
align-content
justify-contentと似ていますが方向が違います。
justify-contentはmain-axis、align-contentをcross-axisに沿って反映されます。
.containerにalign-content: center;
をつけてみます。
すると、、、
あれ?cross-axisの方向(この場合縦)に中央揃えされてない・・・
なぜなら、cross-axisは上から下で縦方向に余分なスペースがないからです。
align-contentは複数の列・行(この場合box)がある時に使えます。
なので、.containerにflex-wrap: wrap;
を追加して、.boxにwidth: 33.3333%;
をつけてみます。
こんな感じ
.container {
display: flex;
border: 5px solid royalblue;
height: 100vh;
flex-wrap: wrap;
}
.box {
width: 33.3333%;
}
すると先ほどflex-wrapのとこでやったようになります。
*align-contentのデフォルトはstretch
.conatainerにalign-content
をいろいろつけてみます。
flex-start
ここで、.boxの中身を一つを2行にしてみる
<div class="box box2">2<br>
hello
</div>
すると
こんな感じで同じ列の高さも一緒に変わります。
flex-end
htmlを元に戻してflex-endに変えると
space-between
space-around
center
Tip
justify-content: center;
とalign-content: center;
で縦横中央揃え
わかりにくいかもなのでboxを減らしてみます
こんな感じで簡単に縦横中央揃えできます〜^ ^
align-self
個別のbox(flex-item)にstretch、center、flex-start、flex-end、baselineをつけれます。
見た方が早いので、どういうことか例を見てみましょう〜
.containerにalign-items: flex-start;
、.boxにwidth: 33.3333%;
を追加します。
すると以下のようになります。
以下でbox〇〇にalign-selfをつけていきます。
.container {
display: flex;
border: 5px solid royalblue;
height: 100vh;
align-items: flex-start;
}
.box {
width: 33.3333%;
}
.box1 {
align-self: stretch;
}
.box3 {
align-self: center;
}
.box5 {
align-self: flex-start;
}
.box7 {
align-self: flex-end;
}
.box9 {
align-self: baseline;
}
すると以下のようになります。
今までやったのと同じですね。
「align-selfはflex-item1つ1つそれぞれの表示を変えれる」と覚えていていいかと思います。
flex-grow / shrink / basis
ここで少しHTMLを変えます。
HTML
<div class="container">
<div class="box box1">1</div>
<div class="box box2">two</div>
<div class="box box3">threeee</div>
<div class="box box4">four</div>
<div class="box box5">five</div>
<div class="box box6">six</div>
</div>
boxそれぞれ中身の文字の長さが違うようにします。
CSS
* {
box-sizing: border-box;
}
.box {
color: white;
font-size: 20px;
text-align: center;
padding: 10px;
}
.box1 { background: #FDA403 }
.box2 { background: #11CBD7 }
.box3 { background: #C51350 }
.box4 { background: #61B292 }
.box5 { background: #F2855E }
.box6 { background: #6A65D8 }
.container {
display: flex;
}
.containerにdisplay: flex;
をつけます。
すると表示はこうなります。
ここで.boxにflex: 1;
をつけると
横幅いっぱいに広がって、右に空いたスペースをそれぞれ均等に埋めてくれます。
.box2にflex: 2;
をかけると、、、
box2だけが他の倍の幅になりました。
flexには3つプロパティがあります
それが、flex-grow、flex-shrink、flex-basis
flex-growとは?
「余分なスペースがある時にboxをどう分割して表示するか」
例:
HTML
<div class="container">
<div class="box box1">one</div>
<div class="box box2">two</div>
</div>
CSS
//ここから上はこれまでと同じ
.container {
display: flex;
}
この時の表示はみなさんのご想像通り以下
.boxにflex-grow: 1;
をかけると、、、
右側の余分なスペースにboxがそれぞれ同じ幅で広がります。
flex-basisとは?
とりあえず例を見て見ましょう
CSS
.box1 {
flex-basis: 400px;
}
.box2 {
flex-basis: 400px;
}
それぞれ400pxの幅になります。
ブラウザの幅を狭めると・・・
はみ出ないし、floatのように折り返しません。
*文字がでかすぎるとはみ出ます。
ブラウザの幅を元に戻して.box1にflex-grow: 1;
をつけてみます。
すると、
box1が余分なスペース分広がって、box2は400pxの幅のままです。
.flex-shrinkとは?
ざっくりいうとflex-growの逆です。
flex-growは余分なスペースに対してbox達をどうgrow(伸ばす)するかでした。
それに対して、flex-shrinkはブラウザの幅が狭くなってきてスペースがなくなってきた時にbox達をどうshrink(縮める)するかです。
例を見て見ましょう〜〜
CSS
//ここから上はこれまでと同じ
.container {
display: flex;
}
.box1 {
flex-basis: 400px;
flex-shrink: 10;
}
.box2 {
flex-basis: 400px;
flex-shrink: 1;
}
さてどうなるか・・・
わざとbox1のshrinkの数字を大きくしているので、その分box2より縮んでいますね。
実際に使うときは、flex-growとかflex-shrink、flex-basisといちいち書かなくてオッケーです。
以下のように書けば簡単です
flex: growの値 shrinkの値 basisの値;
Tip
flex-directionをcolumnにした時にflex-growなどを使いたい場合はheightを持たせないと反映されません。
例:height設定なし
HTML
<div class="container">
<div class="box box1">one</div>
<div class="box box2">two</div>
<div class="box box3">threeee</div>
<div class="box box4">four</div>
<div class="box box5">five</div>
<div class="box box6">six</div>
</div>
CSS
//ここから上はこれまでと同じ
.container {
display: flex;
flex-direction: column;
border: 10px solid royalblue;
}
.box {
flex-grow: 1;
}
.box3 {
flex-grow: 10;
}
*わかりやすいように.containerにboderをつけています。
flex-growを設定していますが、余分なスペースがないので反映されません。
heightの設定あり
.containerにheight: 100vh;
を追記します。
すると余分なスペースができるので以下のようにflex-growが反映されます。
まとめ:FlexBoxは便利なので覚えておきましょう〜
ブラウザのサポートはこんな感じでモダンブラウザでは普通に利用できます。
*ベンダープレフィックスを忘れずにしておきましょう!
基本的なFlexboxの使い方に触れてきましたが、まだまだ応用できるので、さらに詳しく知りたい人はWes BosさんのFlexBoxのコース「What The FlexBox」をみてみてください。無料ですよ〜
What The Flexbox?!
A simple 20 video course that will help you master CSS Flexbox
FlexBoxでのレスポンシブのナビゲーションやレイアウトなども解説してあります。
英語が苦手な人でも字幕があるし、再生スピードも変更できるので一度みてみてください。
以上、「初心者向けFlexBoxの基本的な使い方」でした〜
では〜