flexbox/space-betweenでのカード型レイアウト

モバイル:1カラム・PC:2カラム

アイテムの並べ方はspace-betweenで両端に揃えて均等配置となるようにしておくと、アイテム自身の幅だけ指定すれば横方向の段間のサイズ指定はしなくても良いというメリットがある。
縦方向のアイテム間余白については「複数カラムになった場合の1行目」を一括して指定するセレクタやプロパティが存在しないため、上下については一律に上marginをつけた上で親要素側にマイナスの値のmargin(ネガティブマージン)をつけることで相殺する方法を採用している。

.cardList {
  display: flex;  /* flexbox化 */
  flex-direction: column;  /* 縦並びにする */
  margin-top: -20px;  /* 1行目の上マージンを相殺 */
}
.cardList__item {
  margin-top: 20px;
}
/*2カラム*/
@media screen and (min-width: 768px),print {
  .cardList {
    flex-direction: row;  /* 横並びにする */
    justify-content: space-between;  /* アイテムを両端に揃えて均等配置 */
    flex-wrap: wrap;  /* 折り返して複数行にする */
  }
  .cardList__item {
    width: calc((100% - 20px) / 2);  /* アイテムの幅を指定 */
  }
}

モバイル:1カラム・PC:3カラム

3カラム表示にする場合も基本的には2カラムと同じだが、space-betweenでレイアウトする場合、必ずアイテムが左右両端に揃ってしまうため、最終行にアイテムが2つしかないと、意図したレイアウトにならない。
最終行だけ左詰めにするといったプロパティはflexboxには存在しないため、あらかじめ末尾にアイテムと同じ幅を持つ空の疑似要素を入れておくというテクニックが必要となる。

/* 3カラム */
@media screen and (min-width: 992px),print {
 .cardList__item {
  width: calc((100% - 40px) / 3);  /* アイテムの幅を指定 */
 }
 .cardList::after {  /* 最終行を左詰めにする */
  content: "";
  display: block;
  width: calc((100% - 40px) / 3);
 }
}

モバイル:1カラム・PC:4カラム

4カラム表示にする場合も最終行の左揃え問題が発生するため、after疑似要素だけでなくbefore疑似要素も同様に作成しておく。ただし、before疑似要素は要素の先頭に配置されてしまうため、orderプロパティを使って末尾に移動させておく必要がある。
なお5カラム以上になる場合は物理的にdiv要素などで空要素を入れておかなければならなくなるため、そもそもspace-betweenではない方法を検討したほうが良い。

/* 4カラム */
@media screen and (min-width: 1200px),print {
  .cardList__item {
    width: calc((100% - 60px) / 4);  /* アイテムの幅を指定 */
  }
  .cardList::before,  /* 最終行を左詰めにする */
  .cardList::after {
    content: "";
    display: block;
    width: calc((100% - 60px) / 4);
  }
  .cardList::before {
    order: 1;  /* before疑似要素を末尾に移動 */
  }
}
inserted by FC2 system