Flexboxの均等割り付けをCSSのみで左揃えにする方法
2018.08.21
Flexboxで均等割り付けを実現できる「justify-content: space-between」は自動でマージンも計算してくれるため非常に使い勝手が良く、インフォメーションをグリッドレイアウト風に並べる時など、ついつい多用してしまいます。
- Box01
- Box02
- Box03
- Box04
上の例のように一行に全て入りきるか「flex-wrap: no-wrap」を指定した時のように、改行されない場合は問題ないのですが、下の例のように二行になった場合、「justify-content: space-between」では最初と最後のアイテムは端に、残りは等間隔で配置されますので、隙間が大きくなり見た目がよろしくありません。
HTML
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
CSS
#box{ width:100%; display: flex; flex-wrap: wrap; list-style-type: none; justify-content: space-between; border-radius: 4px; background: #efefef; } #box li{ width:21%; color: #fff; margin-bottom: 2.5%; border-radius: 4px; background: #60B99A; }
RESULT
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
上の結果の通り、Box05とBox06の間に大きな隙間が出来てしまいました。
ちなみに下の結果のように初期値の「justify-content: flex-start」で並べると左揃えにはなりますが、マージンを空かすために「margin-right」等を指定する事になるので、左右どちらかの端にマージン分の隙間が出来てしまいます。
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
これを解決するために、無理やり見えない要素を最後尾に足したり、Javascriptで制御する方法もあるのですが、あまりスマートではありません。できればCSSのみでなんとかしたい所。
そこで役立つのが、要素の最後尾にスタイルを指定できる「last-child」疑似クラスと、何個目かの要素にスタイルを指定できる「nth-child」疑似クラスの合わせ技です。
HTML
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
CSS
#box{ width:100%; display: flex; flex-wrap: wrap; list-style-type: none; justify-content: space-between; border-radius: 4px; background: #efefef; } #box li{ width:21%; color: #fff; font-size: 2.2vmin; padding: 1.5vmin; margin-bottom: 2.5%; border-radius: 4px; background: #60B99A; } #box li:nth-child(4n+2):last-child { margin-right: calc(21% * 2 + ((100% - 21% * 4) / 3) * 2); } #box li:nth-child(4n+3):last-child { margin-right: calc(21% * 1 + ((100% - 21% * 4) / 3) * 1); }
RESULT
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
疑似クラス「:nth-child(4n+2):last-child」の部分を説明すると、2つ目の要素から始まって、4個ずつ飛ばして選択した要素が最後の要素ならば、右に空白分のマージンを空けるように指定しています。(4n+2)の2の部分は疑似クラスを使って調べる"位置"になりますので、並べたい個数によって増減させて下さい。調べる位置とマージンの方向を変えれば右揃えも可能です。
左端を表す「:nth-child(4n+1):last-child」と右端の要素への適用は不要です。
汎用性を高めるために「margin-right」の数値指定にcalcを使っていますが、ここにはあらかじめ計算した数値を記入しても問題ありません。
ちなみに「calc(21% * 2 + ((100% - 21% * 4) / 3) * 2)」の中身も簡単に説明すると calc(子要素の幅 * [一行に並べたい個数-位置] + ((全体の幅 - 子要素の幅 * 一行に並べたい個数) / マージンの個数 ) * [一行に並べたい個数-位置]) と言った具合です。
"マージンの個数"は単に"一行に並べたい個数"から1引いた数になります。
他にも「margin-right」にautoを指定して「margin-left」にマージンの幅を入れる方法でも対応可能です。
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
- Box07
このように行が増えても問題ありません。
- Box01
- Box02
- Box03
- Box04
- Box05
- Box06
- Box07
- Box08
- Box09
- Box10
同じような考え方で「justify-content: flex-start」の端の要素から余分なmarginを消し去る処理を行っても良いと思いますが、逆にあらかじめ全体を計算しておく必要があるので面倒でした。
Copyright © 2018, Mo-ja.net All Rights Reserved.
この記事には目次がありません