カード型コンテンツの高さを揃えて、レスポンシブにする方法
タイトルの長さが異なっても、複数のカードの高さを揃える方法をちゃんと知っておきたかったので、さらにそれをシンプルにレスポンシブ対応させる方法について、アレンジをしてみました。
カード型レイアウト1点についての記事「カード型のレイアウトをつくる方法」の続きになります。
flexboxの要素として2021年に主要なブラウザ全てに対応した、gapプロパティも使いながら整えていきます。
カード型レイアウトのHTML&CSS設定を確認
まずは、全体のコードがこちらになります。
HTMLのコード
<section class="container">
<div class="container__wrapper">
<div class="card">
<figure class="card__img">
<img src="img.jpg" />
</figure>
<h3 class="heading card__item flexible">box-title</h3>
<p class="ellipsis card__item">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<time class="card__time card__item small" datetime="2021-12-01"
>2021 12.01
</time>
</div>
<div class="card">
<figure class="card__img">
<img src="img.jp" />
</figure>
<h3 class="heading card__item flexible">
box-titlebox-titlebox-titlebox-titlebox-title
</h3>
<p class="ellipsis card__item">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<time class="card__time card__item small" datetime="2021-12-01"
>2021 12.01
</time>
</div>
<div class="card">
<figure class="card__img">
<img src="img.jp" />
</figure>
<h3 class="heading card__item flexible">box-title</h3>
<p class="ellipsis card__item">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<time class="card__time card__item small" datetime="2021-12-01"
>2021 12.01
</time>
</div>
</div>
</section>
CSSのコード
/* ===============================================
#common
=============================================== */
html {
font-size: 62.5%;
line-height: 1.4;
color: #082b50;
}
body {
font-size: 1.6rem;
}
img {
width: 100%;
height: auto;
-o-object-fit: cover;
object-fit: cover;
}
.heading {
font-size: 2.4rem;
}
.small {
font-size: 1.3rem;
color: #79767d;
}
.container {
width: 100%;
max-width: 960px;
margin: 100px auto;
}
/* ===============================================
#Card Styling
=============================================== */
.container__wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
padding:0 20px;
gap: 20px;
}
.card {
box-shadow: 1px 1px 3px rgba(106, 131, 152, 0.2);
display: flex;
flex-direction: column;
width: calc(100% / 3 - 20px * 2 / 3);
background-color: white;
}
@media (max-width: 768px) {
.card {
width: calc(50% - 20px / 2);
}
}
@media (max-width: 414px) {
.card {
width: 100%;
}
}
.card__item {
padding: 10px 10px 0 10px;
}
.card__time {
color: #888888;
text-align: right;
padding-bottom: 10px;
}
.ellipsis {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
.flexible {
flex-grow: 1;
}
コードのポイント3つ
コンテンツ同士の、隙間の調整
flex要素にもgapプロパティが使えるので、card3つを囲むwrapper要素に対して、
.container__wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
padding:0 20px;
gap: 20px;
}
上記の様に、cardの要素同士の行や列の隙間を、gapプロパティで20pxに設定しています。
さらに、レスポンシブで幅が狭くなった際にも、paddingで左右のそれぞれの端に20pxずつ余白が確保される様になります。
レスポンシブ対応
カード全体を囲うcardのクラスに対し、メディアクエリをつかって、PC/タブレット/スマホの場合それぞれで幅を変更して、3つ→2つ→1つに並べるように変化させています。
.card {
width: calc(100% / 3 - 20px * 2 / 3);
}
@media (max-width: 768px) {
.card {
width: calc(50% - 20px / 2);
}
}
@media (max-width: 414px) {
.card {
width: 100%;
}
}
PC幅では、それぞれのカードの幅を、width:100% / 3から「20px * 2 / 3」ずつ引くことで、40px(20pxのすきまが2個分)できるようにして、3つ並べています。
タブレット幅だと、width: 50%;から、「20px / 2」ずつ引くことで、全体として20pxのすきま1個分を確保して2つ並べています。
SP幅の際は、width:100%;に設定して、1つずつ並べています。
文字量が違う時の高さを揃える
そのままだと、見出しの長さが異なる際に、ガタガタして見え綺麗ではないので、見出しに下記を加えることで高さを揃えています。
.flexible {
flex-grow: 1;
}
意味合いとしては、カードの要素=display:flexの中に子要素がいくつかある中、見出しにflex-grow :1;を指定することにより、カードの要素中の空いているスペースが見出し部分に全て割り当てられることになるので、結果として見出しの高さが揃って見えます。
gapプロパティについて
Flexboxで使用されるgapプロパティは、2021年4月からはsafari 14.1も対応が決まったことで、IE以外の主要なブラウザでは全て対応済みになりました。
gap: 〇〇px; | 値が1つで、「 行」と「列」の間のすきまを指定 |
gap:◯px ◯px; | 値が2つで、「行」/「 列」の間のすきまをそれぞれ指定 |
row-gap: ◯px; | 「行」の間のすきまを指定 |
column-gap: ◯px; | 「列」の間のすきまを指定 |