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.
この記事には目次がありません