Category
ウェブ制作

カルアカブログ

よく使うタイル(カード)デザインを CSS のパターン別でご紹介

こんにちは、フロントエンドエンジニアのかみーゆです。

よくギャラリーや記事の一覧などが並んだ、タイル(カード)を並べたようなレイアウトを見かけませんか?

こんな感じで無限にカードを並べたい時の実装方法をいくつかパターンでご紹介します。

目次
  1. みんなお馴染み float で実装する方法
    1. パターン1:疑似クラス:nth-child() で余白を調整して並べる
    2. パターン2:ラッパーを1個入れ、はみ出た部分をネガティブマージンで隠す
  2. パターン3:子要素をインライン扱いする
  3. パターン4:レイアウトモジュール・フレックスボックスを使う
  4. パターン5:レイアウトモジュール・グリッドを使う
  5. まとめ

みんなお馴染み float で実装する方法

昔ながらの float で実装する方法です。

float は、要素を親ブロックの左右どちらかに沿うように設置し、テキストやインライン要素がその周りを回りこめるようにするプロパティです。
余談ですが、ブロック要素の背景やボーダーなどは float を指定した要素の下にもぐりこんでしまいますのでご注意を。

パターン1:疑似クラス :nth-child() で余白を調整して並べる

float で兄弟要素のグループの中での位置に基づいて選択できる疑似クラス:nth-child()を使う方法を紹介します。

カードは一列に3つ並ぶように設定してみました。

カードの幅は余白をのぞいて 33.333% になります(割り切れないので四捨五入してます)。カードとカードの間に余白がないと見栄えが悪いので右側に余白を入れて以下みたいに配置されるよう、コーディングしてみます。

右側に 15px ほど margin を入れ、右端に来る(3の倍数の位置)カードの右の余白が0 になるように設定します。
1列で右側に余白が必要な要素の数は2こなので余白の合計は 30px になります。calc関数を使って、width を 33.333% から 10px マイナスして親要素にすっぽり収まるようにします。

CSS
width: calc(33.333% - 10px);

親要素に overflow: hidden; をセットして float の回り込みを解除します。float を解除するには clearfix を使う方法もありますが、今回は割愛します。

HTML
<div class="card pattern1">
  <div class="card_item">Card 1</div>
  <div class="card_item">Card 2</div>
  <div class="card_item">Card 3</div>
  <div class="card_item">Card 4</div>
  <div class="card_item">Card 5</div>
</div><!-- / パターン 1 -->
CSS
.pattern1.card { overflow: hidden; }

.pattern1 .card_item {
  float: left;
  width: calc(33.333% - 10px);
  margin: 0 15px 15px 0;
}

.pattern1 .card_item:nth-child(3n) {
  margin-right: 0;
}

パターン2:ラッパーを1個入れ、はみ出た部分をネガティブマージンで隠す

同じように float を使うのですが、はみ出た部分を隠すパターンをご紹介します。カードの親要素は最初からネガティブマージンで右側に余白分右にはみ出させて、全体を <div> でラップし、はみ出た部分を隠します。

昔、全てのブラウザにまだ :nth-child() が実装されておらず、このやり方で実装した記憶があります。

デメリットは一個ラップ用のタグが増えることです。

HTML
<div class="card_wrapper pattern2">
  <div class="card">
    <div class="card_item">Card 1</div>
    <div class="card_item">Card 2</div>
    <div class="card_item">Card 3</div>
    <div class="card_item">Card 4</div>
    <div class="card_item">Card 5</div>
  </div>
</div><!-- / パターン 2 -->
CSS
.pattern2.card_wrapper {
  width: 100%;
  overflow: hidden;
}

.pattern2 .card { margin-right: -15px; }

.pattern2 .card_item {
  float: left;
  width: calc(33.333% - 15px);
  margin: 0 15px 15px 0;
}

パターン3:子要素をインライン扱いする

子要素を inline-block (インライン)として扱うことにより、横並びを実装する方法もあります。この方法だとタグをテキストのように扱うことができるのですが、改行も一文字としてカウントされ、要素と要素の間にスペースが入ってしまうという問題が起こります。

改行せずに一行で書けば解決しますが、可読性も下がるのでオススメしません。

その対策として、親要素に一度 font-size: 0; を指定して、改行の1文字を見た目上隠してしまいます。その代わり子要素で文字サイズを指定し直します。

HTML
<div class="card pattern3">
  <div class="card_item">Card 1</div>
  <div class="card_item">Card 2</div>
  <div class="card_item">Card 3</div>
  <div class="card_item">Card 4</div>
  <div class="card_item">Card 5</div>
</div><!-- / パターン 3 -->
CSS
.pattern3.card {
  font-size: 0;
}

.pattern3 .card_item {
  width: calc(33.333% - 10px);
  display: inline-block;
  font-size: 16px;
  margin:0 15px 15px 0;
}

.pattern3 .card_item:nth-child(3n) {
  margin-right: 0;
}

パターン4:レイアウトモジュール・フレックスボックスを使う

IE9 のサポートをしなくなった今、レイアウトモジュール・フレックスボックスを使うのが一番手っ取り早いです。

先に紹介した float や インラインで横並びを実装すると中に入るコンテンツ内容のボリュームにばらつきが出てしまったケースでは、以下のようにカードの高さ(height)が揃わないといったような問題が発生します。

そのため、幅が常に変わるレスポンシブデザインなどでは高さをコントロールするのが難しく、JS を使ったりコンテンツ量に制限をして高さが揃うように工夫しなければなりませんでした。

フレックスボックスを利用すれば、勝手に一番高さのあるカードに他のカードを揃えてくれるので、そんな面倒な問題もあっさり解決してくれます。

HTML
<div class="card pattern4">
  <div class="card_item">Card 1</div>
  <div class="card_item">Card 2</div>
  <div class="card_item">Card 3Card 3Card 3Card 3Card 3Card 3</div>
  <div class="card_item">Card 4</div>
  <div class="card_item">Card 5</div>
</div><!-- / パターン 4 -->
CSS
.pattern4.card {
  display: flex;
  flex-wrap: wrap;
}

.pattern4 .card_item {
  width: calc(33.333% - 10px);
  margin:0 15px 15px 0;
}

.pattern4 .card_item:nth-child(3n) {
  margin-right: 0;
}

パターン5:レイアウトモジュール・グリッドを使う

新しいレイアウトモジュール・グリッドで横並びにする方法もあります。
フレックスボックス同様、自動で高さを揃えてくれます。それよりも、嬉しいのはコードの少なさです。親要素にたった3行 CSS を書くだけで、カードデザインの実装が可能です。

HTML
<div class="card pattern5">
  <div class="card_item">Card 1</div>
  <div class="card_item">Card 2</div>
  <div class="card_item">Card 3Card 3Card 3Card 3Card 3Card 3</div>
  <div class="card_item">Card 4</div>
  <div class="card_item">Card 5</div>
</div><!-- / パターン 5 -->
CSS
.pattern5.card {
  display: grid;
  grid-template-columns: repeat(3, calc(33.333% - 10px));
  grid-gap: 15px 15px;
}

上記コードは IE 未対応です。

書き方に癖はありますが、列や列の数が固定のレイアウトであれば、IE 対応可能です。
IE 独自の書き方を結構追記しなければならず、コーダー初心者には結構辛いと思います。

なので、どうしてもグリッドを使いたい時は polyfill という JS ライブラリを利用するといいです。ただし、全てに対応してないようなのでご注意ください。

css-grid-polyfill

まとめ

いかがだったでしょうか?

今回は横並びにするタイル(カード)デザインを実装する方法をご紹介いたしました。

用途によって使い分けることができますので、ぜひ試してみてください。

Tags
css
フロントエンド

関連記事

関連サービス