【CSS初心者の方向け】display:flex-フレックスボックスの使い方をまとめました!
フレックスボックスの利用について生徒さんから「わかるようで、わからないようで」とよく相談されます。
そこで、絶対理解しておきたい使い方をまとめました。
最低限、これをおさえておけばOK!です。
display:flexとは何か
そもそも、display:flexとは何か?ですが、CSSでレイアウトを指定する方法の一つで、フレキシブルボックスとも呼ばれています。
レイアウトとは、写真の位置は右、文章は左など、コンテンツの配置を指定することです。
古くからあるプロパティとしてはfloatやpositionがありますが、最近はこのフレキシブルボックスが便利で、よく利用されています。
では、display:flexを指定するとどうレイアウトされるのか、確認していきます。
display:flexを指定すると横並びになる
例えばdiv要素などのブロックレベルと呼ばれる要素(タグ付けすると、改行もされるタグ)は、レイアウトの指定をしなければ通常、縦に並んで表示されます。
例えば、今回はdiv要素にクラスitemをつけて4つ用意しました。
わかりやすいように、余白と背景を指定しています。
レイアウトについてはCSSで指定は何もしていないので、以下のように要素のボックスは縦に並びます。
<body>
<div class="item">一つめのdiv</div>
<div class="item">二つめのdiv</div>
<div class="item">三つめのdiv</div>
<div class="item">四つめのdiv</div>
</body>
.item:nth-child(1){
background-color:tomato;
}
.item:nth-child(2){
background-color:orange;
}
.item:nth-child(3){
background-color:aqua;
}
.item:nth-child(4){
background-color:green;
}
.item{
padding:10px;
}
では、この4つのボックスを横に並べたいときどう指定すればよいでしょうか?
フレキシブルボックスを使えば、簡単にレイアウトの指定を行うことができます。
横並びにしたい要素を一つのタグで囲み、その囲んだタグにdisplay:flexと指定すればOKです。
.container{
display: flex;
}
つまり、display:flexを指定した要素の子要素が、横並びになります。
この時、display:flexを指定したタグを「フレックスコンテナ」、横並びになった子要素を「フレックスアイテム」と呼んだりします。
書籍やサイトでフレキシブルボックスについて調べると、この言葉がよく出てきます。
何のこと?とならないように、整理しておきましょう!
display:flexで横並びにすると、何とか1行に収めようとする
display:flexを指定すると、横並びになることは確認済みです。
では、コンテナとアイテムに幅の指定があって、横に並んでいるアイテムの幅の合計が、コンテナの幅を超えた場合(つまり、アイテムがコンテナに収まらない幅になっていた場合)はどうなるのでしょうか?
実は、アイテムは勝手に縮小されてきちんんと横一行に並びます。
display:flexが指定された子要素の各アイテムは、指定されている幅を無視して自動的に縮めてでも、何とか1行に収めようとするのです。
では、widthプロパティで幅を指定してみましょう。
アイテムに300pxの幅を指定します。アイテムは4つありますので、コンテナは1200px以上必要ですが、あえてコンテナに800pxを指定してみます。
なお、paddingは縦だけの指定に変更しておきます。
.item{
padding:10px 0;
width:300px;
}
.container{
display: flex;
width: 800px;
}
表示結果を見ていただくと一目瞭然!
コンテナの幅が足りないはずなのに、アイテムは横に並びます。
これは後にご紹介する
flex-shrinkプロパティ(アイテムの縮小する比率を指定するプロパティ)の初期値が1(等しい比率で縮小する指定)
flex-wrapプロパティ(アイテムを折り返しを指定するプロパティ)の初期がno-wrap(折り返さない指定)
であるからなのですが…。
これらのプロパティの詳細は後ほど…。
今の段階では「display:flexが指定されたアイテムは、こちらから何も指定しなければ必ず1行に並ぶ」と覚えておきましょう。
主軸と交差軸が設定される
フレキシブルボックスを正しく理解するためには、主軸と交差軸について理解しなければなりません。
display:flexが指定された要素のフレックスアイテムは、主軸に沿って並びます。
つまり、左から右への主軸が設定されることによって、アイテムは左から右へ並びます。
また、主軸と垂直に交わる軸も設定され、その軸を交差軸と呼んでいます。
後ほどご紹介する、フレキシブルボックスのプロパティ群で、この主軸の方向を変えたり、交差軸方向に整列されたりといった操作を行います。
2つの軸について、理解しておきましょう。
フレックスコンテナ、フレックスアイテムになった要素には、フレキシブルボックス専用のプロパティが有効になる
アイテムが横に並ぶことを中心にお話していますが、display:flexを指定することで実は、もう一つ大きな変化が起こっています!
コンテナとアイテムにフレキシブルボックスで使用されるプロパティが有効になる!という点です。
これらのプロパティはdisplay:flexを指定しているからこそ使用できるプロパティです。通常の状態では使用できません。
フレキシブルボックスで使用できるプロパティ群
プロパティ群についてご紹介していきますが、読み進めていただく際にポイントが一つあります。
フレックスコンテナに指定するものと、フレックスアイテムに指定するものがあるということです。
フレキシブルボックスのプロパティは、この2つに大きく分かれています。
コンテナに指定するべきプロパティをアイテムに指定しても、まったく効果がありません!
どちらに指定するものなのかな?というところを意識しながら、読み進めてください。
まずはざっとフレキシブルボックスのプロパティ群を確認!
それでは、最初にざっとフレキシブルボックスのプロパティ群について全体像を確認しましょう。
ここでご紹介するのは、この記事で紹介しているプロパティです。紹介しているプロパティ以外にも存在しますが、よく利用するプロパティを厳選してまとめてみました。
指定する要素 | プロパティ名 | 概要 | 値 |
---|---|---|---|
コンテナに指定する | flex-wrap | アイテムを1行に収めるか、複数行にするか | no-wrap(初期値) 1行にする wrap 複数行にする |
flex-direction | 主軸の方向を決める (アイテムを並べる方向を決める)コンテナに指定する | row (初期値)左から右 row-reverse 右から左 column 上から下 column-reverse 下から上 | |
justify-content | アイテム全体の主軸方向の配置 | flex-start(初期値) 左 center 中央 flex-end 右 space-between アイテムの間に等間隔の余白をあける | |
align-items | アイテム全体の交差軸方向の配置 | stretch(初期値) アイテムをコンテナの高さいっぱいに配置。 flex-start 上 flex-end 下 center 中央 baseline ベースラインに合わせる | |
align-content | 複数行のアイテム全体の配置 (アイテム間の余白のとり方) ※コンテナにアイテム以上のheightの指定が必要 ※アイテムにflex-wrap:wrapの指定が必要 | flex-start(初期値) 上 center 中央 flex-end 下 space-between アイテムの間に等間隔の余白をあける | |
アイテムに指定する | align-self | 指定されたアイテムの交差軸方向の配置 | stretch(初期値) アイテムをコンテナの高さいっぱいに配置。 flex-start 上 flex-end 下 center 中央 baseline ベースラインに合わせる |
order | アイテムの並び順 | 0(初期値) 整数を指定。 小さい値が指定された要素から並ぶ。 | |
flex-shurink | アイテムをどのくらい縮めるか、その倍率 | 1(初期値) 整数または小数部分のある数値を指定。 | |
flex-grow | アイテムをどのくらい伸ばすか、その倍率 | 0(初期値) 整数または小数部分のある数値を指定。 |
※justify-content、align-items、justify-self、align-selfの値にあるアイテムの配置はflex-diretionがrow(初期値)の場合の結果です。
主軸の方向を変えることができるflex-direction【コンテナに指定】
横並びになったフレックスアイテムですが、左から右へと並んでいます。
これは主軸の方向が左から右へ設定されているからでした。
この主軸ですが、CSSで方向を変えることができます。
主軸の方向を変えるということは、アイテムを縦方向にしたり、右から左へ並べたり、並べる方向を変えることができるということです。
主軸の方向を設定するのが、flex-directionプロパティです!
このflex-directionプロパティは、初期値はrowとなっています。rowは左から右へ並ぶ指定なので、display:flexを指定すると左から右へとアイテムは並びます。
.container{
display: flex;
flex-direction: row;
}
row-reverseを指定すると、右から左へ並びます。
.container{
display: flex;
flex-direction: row-reverse;
}
columnを指定すると、上から下へ並びます。
.container{
display: flex;
flex-direction: column;
}
column-reverseを指定すると、下から上へ並びます。
.container{
display: flex;
flex-direction: column-reverse;
}
アイテムを1行に収めるか、複数行にするか指定するflex-wrap【コンテナに指定】
フレックスアイテムは1行に収まる、それはフレックスコンテナの幅が不足していても…ということでしたが、実は、flex-wrapの初期値がno-wrapだから、ということになります。
no-wrapは、フレックスアイテムを「1行にしますよ」という指定だからです。
flex-wrapはCSSで変更することがもちろんできます。
wrapを指定すれば、フレックスアイテムは勝手に縮んだりすることはなく、フレックスコンテナの幅が不足した場合は複数行になって表示されるようになります。
例えば、コンテナの幅を800pxに、アイテムの幅を300pxにした場合、アイテムを縮めなければ800pxの幅には収まり切れず、アイテムは1行に2つまでしか収まりません。
flex-wrapを変更しなければ、no-wrapで1行に収めますので、アイテムは勝手に縮みます。
.item{
padding:10px 0;
width:300px;
}
.container{
display: flex;
width:800px;
}
wrapに変更すると、アイテムは縮むことなく2行になります。
.container{
display: flex;
width:800px;
flex-wrap:wrap;
}
幅のdisplay:flexを指定すれば、幅のことは気にすることなく、自動的に横に並ぶのは便利ですが、幅を変えずに複数行で表示したいときもあります。
その際は、flex-wrapのプロパティを変更してみましょう!
アイテム全体の主軸方向の配置を決めるjustify-content【コンテナに指定】
「主軸方向の」がポイントです。
主軸方向はflex-directionプロパティで変更することができます。
そのため、flex-directionが初期であるrowやrow-reverseの場合は左右方向の配置の指定になりますが、flex-directionでcolumn、column-reverseを指定した場合は、上下方向の配置の指定となります。
では一通りの値を試してみましょう!
なお、これから試す配置はflex-directionがrowの場合の結果となります。
flex-start(初期値) 左寄せで配置
.container{
display: flex;
justify-content: flex-start;
}
center 中央寄せで配置
.container{
display: flex;
justify-content: center;
}
flex-end 右寄せで配置
.container{
display: flex;
justify-content: flex-end;
}
space-between アイテムの間に等間隔の余白をあける
.container{
display: flex;
justify-content: space-between;
}
なお、space-betweenに似た値でspace-aroundとspace-evenlyがあります。
space-aroundはアイテムの両側に、アイテム間の余白の半分の余白が入ります。
.container{
display: flex;
justify-content: space-around;
}
space-evenlyはアイテムの両側に、アイテム間と同じ余白が入ります。
.container{
display: flex;
justify-content: space-evenly;
}
アイテム全体の交差軸方向の配置を決めるalign-items【コンテナに指定】
「交差軸方向の」がポイントです。
justify-contentと同様で、flex-directionの値によって、縦方向の指定か横方向の指定かが変わります。
アイテム同士の高さが同じ場合は、指定しても変化がありません。
今回は2つめのdiv要素の文章を2行にしてコンテナの高さを出してから、確認してみましょう。
<div class="container">
<div class="item">一つめのdiv</div>
<div class="item">二つめのdiv<br>2行目を追加</div>
<div class="item">三つめのdiv</div>
<div class="item">四つめのdiv</div>
</div>
stretch(初期値) アイテムをコンテナの高さいっぱいに配置。
.container{
display: flex;
align-items:stretch;
}
flex-start 上に詰めて配置
.container{
display: flex;
align-items:flex-start;
}
center 中央に揃えて配置
.container{
display: flex;
align-items:center;
}
flex-end 下に詰めて配置
.container{
display: flex;
align-items:flex-end;
}
baseline ベースラインに合わせる
この指定は、アイテムのフォントサイズを変更した方が確認しやすいです。
今回は2つめのアイテムだけフォントサイズを大きめにして、指定してみます。
.item:nth-child(2){
background-color:orange;
font-size:30px;
}
.container{
display: flex;
align-items:baseline;
}
文字のベースラインに合わせて、配置されます。
複数行のアイテム全体の配置を決めるalign-content【コンテナに指定】
先ほどalign-itemsプロパティをご紹介しましたが、align-contentも同じような指定になります。
このプロパティのポイントは「複数行の」というところです。
複数行になったアイテムの配置、その行との間の余白をどうするか?を指定するのがalign-contentです。justify-contentプロパティの交差軸版といった感じです。
このプロパティは複数行になったときの余白の設定でもあるので、
- フレックスコンテナにflex-wrap:wrapが指定されている(複数行になっている)
- コンテナの高さが、アイテムの高さよりも大きい(縦方向に余白がある)
状態でなければ、効果がありません。
今回は、フレックスコンテナにheightで余白が出る程度の高さを指定し、align-contentプロパティを指定してみます。
flex-start 上に詰めて配置
.item{
padding:10px 0;
width:300px;
}
.container{
display: flex;
width:800px;
flex-wrap:wrap;
height:150px;
align-content:flex-start;
}
center 中央に揃えて配置
.container{
display: flex;
width:800px;
flex-wrap:wrap;
height:150px;
align-content:center;
}
flex-end 下に詰めて配置
.container{
display: flex;
width:800px;
flex-wrap:wrap;
height:150px;
align-content:flex-end;
}
space-between アイテムの間に等間隔の余白をあける
.container{
display: flex;
width:800px;
flex-wrap:wrap;
height:150px;
align-content:space-between;
}
space-around、space-evenlyの考え方も、justify-contentと同様です。
交差軸方向の配置を個別に指定するalign-self【アイテムに指定】
交差軸方向の配置を指定するプロパティとしてalign-itemsをご紹介しましたが、align-itemsはアイテム全体に統一して配置指定をします。
align-selfはアイテム一つ一つ個別に配置指定ができるプロパティで、指定をするとalign-itemsの指定は無視されて、align-selfの指定が優先されるようになります。
例えば、align-itemsの指定をflex-startにしていて、一つ目のdivだけalign-selfでflex-endを指定した場合、一つ目のdivだけ下揃えで表示されます。
.container{
display: flex;
align-items:flex-start;
}
.item:nth-child(1){
background-color:tomato;
align-self:flex-end;
}
align-selfプロパティの値は、align-itemsと同様の値を指定することができます。
アイテムの表示順を指定するorder【アイテムに指定】
通常アイテムは、HTMLのソースコードの順番でflex-directionで指定された主軸に沿って表示されます。
しかし、orderプロパティを使用すると、フレックスアイテムの表示順を自由に変更することができます。
2番目にあるアイテムを最後に表示したりすることが可能です。
値は整数を指定して、順番はorderの値の小さい順(昇順)で表示されます。
orderを指定していない場合は0の値が初期値です。
そのため、2番目のアイテムにorder:1を指定すると、他のアイテムよりもorderの値が大きくなるため、最後に表示されるようになります。
.item:nth-child(1){
background-color:tomato;
}
.item:nth-child(2){
background-color:orange;
order:1;
}
.item:nth-child(3){
background-color:aqua;
}
.item:nth-child(4){
background-color:green;
}
アイテムをどのくらい縮めるか、その倍率を指定するflex-shrink【アイテムに指定】
フレックスアイテムの幅がフレックスコンテナに収まらない場合、flex-wrapの値を初期値のno-wrapだと、幅を縮小してでも一行に収めます。
この「縮小」ですが、各アイテム同じ比率で縮んでいます。その縮む倍率を指定するのがflex-shrinkで、初期値が1だから、各アイテム1対1の割合(同じ比率)で縮みます。
例えば、あるアイテムだけ縮ませたくない場合、flex-shrinkの値を0に指定すれば縮まなくなります。
.item:nth-child(1){
background-color:tomato;
flex-shrink: 0;
}
.item{
padding:10px 0;
width:300px;
}
.container{
display: flex;
width:800px;
}
アイテムをどのくらい伸ばすか、その倍率を指定するflex-grow【アイテムに指定】
フレックスアイテムは横に並ぶとき、
- アイテムに幅の指定をしていない
- 縮めなくてもフレックスコンテナに収まる幅
だった場合、フレックスアイテムの幅は自動的に、コンテンツに合わせた幅になります。
これはアイテムをどのくらい伸ばすか指定するflex-growプロパティの初期が0のため、アイテムが伸びないからです。
例えば、このアイテムの幅をコンテナに合わせて均等に伸ばしたい場合、すべてのフレックスアイテムにflex-grow:1を指定します。
1対1の割合で(同じ比率)で幅が広がります。
.item{
padding:10px 0;
flex-grow: 1;
}
一つ目のdivだけを伸ばしたい場合は、一つ目のアイテムにだけflex-grow:1を指定します。
.item:nth-child(1){
background-color:tomato;
flex-grow: 1;
}
.item:nth-child(2){
background-color:orange;
}
.item:nth-child(3){
background-color:aqua;
}
.item:nth-child(4){
background-color:green;
}
.item{
padding:10px 0;
}
まとめ
フレックスボックスの授業をすると、新しい考え方でレイアウトをとる必要があったり、プロパティ群が多かったりして、挫折してしまいそうになります。
それでも、一度覚えてしまえばとても便利なフレックスボックス!
苦手な方はぜひ記事を読んで、理解を深めてみてくださいね!