【webサイト】カード型レイアウトを作成する

CSS
円周率π
円周率π

コンテンツブロックがたくさん並んだようなレイアウトを作るにはどうしたらいいのかな?

動点P
動点P

え、また新しい人だ、え~とね、え~とね、

動点Qちゃん
動点Qちゃん

円周率パイさんですね・・・。今回はcssのflexboxを使って作ってみます・・・。

同じ大きさのコンテンツブロックがたくさん並んでいるデザインはどのように作ればいいのかですが、 grid を使う方法も簡単なのですが、IEに対応させるのに面倒なことが多く、後からまたプレフィックスを削除するという手間もあるので、ここは慎重にflexboxを使って基本的なやり方で作成していきたいと思います。

作成するレイアウトの詳細を決める

人物紹介も兼ねてレイアウトを組んでみました。1つ1つの黄色いカードのサイズ、その中の画像、タイトル、テキスト内容などの量を考えてなるべく決定していった方が作りやすいと思います。各カードとカードの間や文字間なども考慮して計算しておくと後で混乱せずに済みます。

カードを一つ作る

とりあえず body タグの中に各カードが収まっている緑のコンテナータグを作り、その中にカード1つ分のdivタグを作ります。画像、タイトル(名前)、テキストを入れて1枚のカードを作ってみます。

とりあえずhtmlで基本的な内容を入力します。

<body>
    <div class="card-container">
        <div class="card">
            <p class="card-image"><img src="q.png" alt=""></p>
            <h2 class="card-title">Qちゃん</h2>
            <p class="card-text">テキスト内容:グラフ上を動く動点Qの鳥。思慮深くて控え目な性格だけど芯の強さはピカイチだよ。
                </p>
        </div>
    </div>
</body>

bodyタグの中に入っている最初のdivタグ card-container が最初にレイアウトした緑の入れ物になります。今は黄色いカードの入れ物が縦横いっぱいに広がってしまっているので見えません。

ここでimgタグがpタグに入っているのですが、どうやら文脈上必要な関連のある画像には p タグ

キャプションなどがつき、画像それ自体で独立しているものには figure タグをつける

ことになっているらしいのですね。

あとそれぞれにクラスが付いていますが、コーディングの範囲を広げない(pタグに影響させない)とか、コーディングの文字数を少なくする(セレクタ名で入れ子状態を深くしすぎない)とか、いろいろ利点があるようです。もちろん違う流派もありますので、各自やりやすいようにすればいいかと思います。

CSSでカードを装飾する

今度はCSSでサイズを決め、装飾を施していきます

ポイント

枠線を含めたサイズをそのコンテンツの外形のサイズとしたいので、全体に

box-sizing: border-box;

を指定しています。

あと画像に枠線をぴったり引きたい場合は img タグそれ自体にborderで指定してください。

画像の方にも計画にはなかった角丸を付けてます。

line-heightでできる余白

内容テキストにline-heightをつけると、一行目の上にも余白ができてしまい、狙ったデザインにできません。

そういうときはfont-sizeで指定したサイズから計算します。(フォントによっては指定したサイズが高さのピクセルとは限らないものもあります。)

例えば今回内容テキストのサイズは20px

20px × line-height 1.7 = 34

つまり一行の上下に14px余計に付いてるわけです。上だけだと7pxですね。

なのでテキスト部分のマージンを

margin: -7px 10px 3px 10px;

にして余分な余白を相殺します。

文章の両端揃え

text-align: justify;

文章の両端揃えを忘れていました、つけておいてください。

@charset "utf-8";

* {
    box-sizing: border-box; 
}

.card-container {
    background: #C7FF86;
    max-width: 960px;
}

.card {
    background:#FCEE21;
    width: 300px;
    border: 10px solid #666666;
    border-radius: 40px;
}

.card-image {
    margin: 10px;
}

.card-image img {
    width: 100%;
    border: 10px solid #666666;
    border-radius: 20px;
}

.card-title {
    margin: 15px 10px;
    font-size: 40px;
    font-weight: bold;
}

.card-text {
    margin: -7px 10px 3px 10px;
    font-size: 20px;
    font-weight: bold;
    line-height: 1.7;
}

カードを複製してflexboxにして並べる

カードの部分を複製して並べただけだと、縦に並んでしまいます。

横に並べたいときは display: flex; を使います。

これだけだとただ横いっぱいにブロックが並ぶことになってしまいますので、折り返してほしいときは flex-wrap: wrap; も一緒につけましょう。

.card-container {
    background: #C7FF86;
    max-width: 960px;
    display: flex;
    flex-wrap: wrap;
}

ちなみにこのカードの高さが揃っているのもflexboxの指定のおかげです。子要素のカードのかたまり自体に高さを合わせるalign-items: stretchが効いています。

マージンを調整する

今度は緑のコンテナに余白があったり、カード間が詰まっているので、そこを調整していきます。

justify-content: space-between;を使う

justify-content: space-between; を使えば簡単です。

要素を等間隔に勝手に並べてくれるので、カードの下のマージンを指定するだけで綺麗に並べることができます。並べたいカードの親要素につけます。

コードはこれです。

.card-container {
    max-width: 960px;
    background: #C7FF86;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
.card {
    background:#FCEE21;
    width: 300px;
    border: 10px solid #666666;
    border-radius: 40px;
    margin-bottom: 20px;
}

ただし問題があって、縮めたときや数が横いっぱい並べるほどには足らないときは、カードが両端においやられてしまいます。これはカッコ悪い…。

なのでこの機能を使うときは縮める必要のないとき、(最近のサイトのカード要素はコンテナとカードごと小さくなっていくものが多いので無理やり折り返しまくらなくても良いと思います。)なら使ってもよいかなと思います。最後の行の数が足りないときは疑似要素を使って解決する方法があるようです。空の透明な要素を入れてもいいんじゃないかなとも思います。

横のマージンを付けて調整する

今度は横のマージンをつけて左寄せのまま折り返す方法です。

ちなみにコンテナの幅に余裕をもたせて普通に左右のマージンをつけてしまう方法もアリだと思います。

今回はコンテナにカードが左右ぴったり入っているので、左だけ、右だけにマージンをつけてしまってもはみ出してしまってうまく並びません。

かといって3の倍数の個数目のカードにnth-of-type(3n)で指定してマージンを0にしても折り返したときに不格好になってしまいます。

.card-container {
    max-width: 960px;
    background: #C7FF86;
    display: flex;
    flex-wrap: wrap;
}
.card {
    background:#FCEE21;
    width: 300px;
    border: 10px solid #666666;
    border-radius: 40px;
    margin-bottom: 20px;
    margin-right: 30px;
}
.card:nth-of-type(3n) {
    margin-right: 0px;
}

こういうときはもう一つ上の親要素を作り、元のコンテナにはネガティブマージンをつけて調整するというやり方があるようです。

コードはこれです。

.wrapper {
    width: 960px;
    display: flex;
    justify-content: center;
    background: #C7FF86;
}
.card-container {
    max-width: 990px;
    display: flex;
    flex-wrap: wrap;
    margin: 0 -30px 0 0;
}
.card {
    background:#FCEE21;
    width: 300px;
    border: 10px solid #666666;
    border-radius: 40px;
    margin-bottom: 20px;
    margin-right: 30px;
}

カードに右マージンをつけるけど、コンテナのマイナスの右マージンで相殺しようという作戦です。

しかし最近のサイトだと、そもそもレスポンシブで縮めたとき無理に折り返さないサイトが多いような…。

コメント