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の部分は疑似クラスを使って調べる"位置"になりますので、並べたい個数によって増減させて下さい。調べる位置とマージンの方向を変えれば右揃えも可能です。

汎用性を高めるために「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.

この記事には目次がありません

関連記事

Flexboxの均等割り付けをCSSのみで左揃えにする方法

CSSのみでふわふわ浮かぶアニメーションを作ってみる

「Where did they go from here」でWelcartに「この商品を見た人はこんな商品も見ています」機能を追加! Welcart補完計画 [3]

「Last Viewed Posts」でWelcartに「最近チェックした商品」機能を追加! Welcart補完計画 [2]

「WP Favorite Posts」でWelcartに「お気に入り」機能を追加! Welcart補完計画 [1]