フレックスボックスの基本的な設定方法についてまとめました。
フレックスボックスとは
フレックスボックス(Flexbox)は、複数の要素を一行や一列に並べたいときに使うCSSの設定です。
要素を均等に並べたいとき、位置合わせをしたいとき、余白の分配などを行いたいときに使用します。
具体的なユースケースについては以下を参照。
フレックスボックスの典型的な用途 - CSS: カスケーディングスタイルシート | MDN
複数の行や列に並べるなら、グリッドの方が適しているかもしれません。
並び方の設定
まずは、並べたいアイテムをdivなどのコンテナに入れ、そのコンテナに対して「display: flex;」を設定します。
横並び
<div class="box1">
<div>ブロック1</div>
<div>ブロック2</div>
<div>ブロック3</div>
<div>ブロック4</div>
</div>
.box1 {
display: flex;
border: 1px solid;
}
「display: flex;」を設定すると、デフォルトで左寄せされ(日本語や英語の場合)、横一列に並びます。
これは並び方を設定するプロパティ「flex-direction」のデフォルト値が「row」だからです。
縦並び
縦並びにするには、flex-directionの値を「columun」にします。
.box2 {
display: flex;
flex-direction: columun;
border: 1px solid;
}
見た目はフレックスボックスを使用しなかったときと同じで、今のところ設定するメリットが感じられないかもしれません。
逆方向
横一列で右から左(日本語や英語の場合)に並べるには、flex-directionの値を「row-reverse」に。
.box-rev1 {
display: flex;
flex-direction: row-reverse;
border: 1px solid;
}
下から上に縦一列に並べるには、値を「column-reverse」に。
.box-rev2 {
display: flex;
flex-direction: column-reverse;
height: 200px;
border: 1px solid;
}
下寄せされています。
折り返し
フレックスボックスのデフォルトの挙動は、並べるものが多くなるとアイテムが収縮します。
ぎゅうぎゅう詰めになっても収まらないときには、設定された横幅を超えて表示されることもあります。
折り返しを可能にするプロパティは「flex-wrap」で、値をwrapにします。
.box-wrap {
display: flex;
flex-wrap: wrap;
width: 250px;
border: 2px solid red;
}
アイテムの大きさ制御
並べるアイテムに大きさ(widthやheight)が設定されていても、上で示したようにコンテナのサイズによってアイテムが収縮します。
大きさを制御するプロパティは3つ。
どれもコンテナではなく、アイテムに対して設定するものです。
- flex-basis
- flex-grow
- flex-shrink
flex-basisでアイテムのサイズを指定します。
初期値は「auto」で、widthやheightが設定されていると、その寸法が適用されます。
何も設定されていない場合、要素の内容がそのままサイズになります。
flex-growはアイテムが伸長する割合です。
初期値は「0」で、アイテムを並べ終え、まだコンテナに余裕があった場合(余白があった場合)でも、アイテムは大きくなりません。
例えば、親のwidthが500px、並べるアイテムのサイズが100px✕2であってもアイテムは100pxを維持します。
それぞれのアイテムのflex-growを「1」にすると、余白の300pxが等分され、(アイテムのコンテンツを考慮しないなら)150pxずつアイテムが大きくなります。
flex-shrinkはアイテムが収縮する割合です。
初期値は「1」。収まらなかったアイテムが収縮していたのは、このプロパティによるものです。
「0」にすると収縮しなくなり、例えば、ひとつを「2」、他を「1」に設定すると、2にしたアイテムは他のアイテムより収縮するようになります。
この3つのプロパティを一括指定できる「flex」があります。
flexは「flex: flex-grow flex-shrink flex-basis;」のように指定しますが、あらかじめ用意された定義の値もあり、
- flex: initial
- デフォルト値。「flex: 0 1 auto」と同義。アイテムはコンテナに入りきらないときに収縮する。余白はそのまま。
- flex: auto
- 「flex: 1 1 auto」と同義。コンテナに余白があればアイテムは伸長、収まらなかったときには収縮。
- flex: none
- 「flex: 0 0 auto」。アイテムの大きさは変わりません。
- flex: 正数
- flex: 1とすると、「flex: 1 1 0」と同じ。flex: 2は、「flex: 2 1 0」と等しくなる。flex-basisが0の状態から伸び縮み。
いくつかサンプルを書きました。
<div class="sample1">
<div class="main-block1">メイン</div>
<div class="sub-block1">サブ</div>
</div>
.sample1 {
display: flex;
width: 300px;
}
.main-block1 {
flex: 3 0 100px;
color: white;
background-color: rgb(224, 29, 29);;
}
.sub-block1 {
flex: 2 0 100px;
color: white;
background-color: rgb(77, 79, 218);
}
コンテナのwidthが300px、メインとサブのflex-basisをともに100pxに設定しています。
余白が100pxあり、メインが3、サブが2の割合で分配されるため、最終的なメインのサイズは160px、サブは140pxとなります。
<div class="sample2">
<div class="main-block2">メイン</div>
<div class="sub-block2">サブ</div>
</div>
.sample2 {
display: flex;
width: 300px;
}
.main-block2 {
flex: 2;
color: white;
background-color: rgb(224, 29, 29);;
}
.sub-block2 {
flex: 1;
color: white;
background-color: rgb(77, 79, 218);
}
コンテナの大きさは300px。
メインが占める割合は2、サブは1です。
300を3等分してそれぞれの割合で振り分けると、メインは200px、サブが100pxに伸長します。
位置合わせ
位置合わせをする場合は、主軸と交差軸を知っておく必要があります。
この軸を決めるのがflex-directionです。
flex-directionの値が「row」か「row-reverse」なら主軸は横方向になり、交差軸は縦方向になります。
同じく「column」や「column-reverse」なら主軸は縦、交差軸は横になります。
前の項目「アイテムの大きさ制御」では主軸に関して、足りないスペースや余白をどのようにアイテムに振り分けるか、もしくは奪うか、ということでした。
位置合わせでは余白を空間に振り分けることで、アイテムの位置を制御します(交差軸のプロパティに一部アイテムを引き伸ばす設定もありますが)。
余白がなければ機能しません。
主軸に対する位置合わせ
主軸のアイテムの配置は「justify-content」で行います。
コンテナに設定。
いくつかを実例で示します。(flex-directionは「row」です)
justify-content: flex-start;
justify-content: flex-end;
justify-content: center;
justify-content: space-between;
他にもあるので以下を参照。
justify-content - CSS: カスケーディングスタイルシート | MDN
交差軸に対する位置合わせ
交差軸のアイテムの配置は「align-items」です。
コンテナに設定。
こちらも実例で示します。
同じくflex-directionは「row」、余白がなければ機能しないのでheightも設定します。
align-items: strech;
ボックス3-2
省略した場合のデフォルト値です。
アイテムは交差軸の方向に引き伸ばされています。
align-items: flex-start;
ボックス3-2
align-items: flex-end;
ボックス3-2
align-items: center;
ボックス3-2
アイテム間のスペースを設定
アイテムの間のスペースは「gap」で指定できます。
これは「row-gap」と「column-gap」の一括指定プロパティです。
pxやemなどの単位を使ったものや、要素に対するパーセンテージで値を書きます。
値がひとつだけなら両方に同じ値が適用。
.box-gap {
display: flex;
gap: 2rem 1rem;
flex-wrap: wrap;
width: 350px;
border: 1px solid;
}
.box-gap div {
flex: auto;
border: 1px solid;
text-align: center;
}