【脱ビギナーCSS】基本のメディアを実装してみる

こんにちは。Web制作フリーランスのホリエです。

今回は、ウェブサイトで頻出するパーツであるメディアをとりあげ、正しいCSSの書き方を考えてみます。

メディアって何?という方のために先に示しておくと、下記のように、画像とテキストが並んだパーツです。よく見ますよね。これを実装していきます。

今回実装するメディアの例
今回実装するメディア
今回実装するメディア(レスポンシブ時)

それでは始めましょう!

完成コードと実装結果

コード

<div class="media">
  <figure class="media__img-wrapper">
   <img class="media__img" src="https://www.blog.hy-webc.com/wp-content/uploads/2021/09/homepage600x400.jpg" alt="コンピューター"> 
  </figure>
  <div class="media__body">
    <h3 class="media__title">
      まるっとホームページ制作パック
    </h3>
    <p>ホームページを持ちたい。ゼロの状態からホームページの立ち上げまで全てお願いしたい・・・しかし時間もコストもかけられない、というお客様向けの事業です。<br>
お客様への入念なヒアリング後、最適なデザインテンプレートをベースに作り込むことで、大幅に工数を減らし、短納期、低価格を実現しています。
    </p>
  </div>
</div>
.media {
  display: flex;  /* ① */
  align-items: center;  /* ① */
}

.media__img-wrapper {
  flex: 0 1 30%;  /* ② */
  margin-right: 3%;  /* ③ */
}

.media__img {
  width: 100%;  /* ④ */
}

.media__body {
  flex: 1;  /* ② */
}

/*最後の要素の下部余白をリセット*/
.media__body > *:last-child {
  margin-bottom: 0;  /* ⑤ */
}

.media__title {
  margin-bottom: 10px;
  font-size: 1.125rem;
  font-weight: bold;
}

/*メディアクエリ適用時*/
@media screen and (max-width: 768px) {
  .media {
    display: block;  /* ⑥ */
  }
  
  .media__img-wrapper {
    margin-right: 0;  /* ⑦ */
    margin-bottom: 20px;  /* ⑦ */
  }
}

実装結果

See the Pen メディア(original) by hori-suke (@hori-suke) on CodePen.

各プロパティの説明

①display: flex; / align-items: center;

画像とテキストを横並びにするためにdisplay: flexを指定しています。また、中央揃えとなるようにalign-items: centerを指定しています。

なお、上端揃えにしたい場合はalign-items: flex-start、下端揃えにしたい場合はalign-items: flex-endにします。比較するとそれぞれ下記のような感じになります。

②flex: 0 1 30%; / flex: 1;

スクリーンサイズが変化したときに、画像とテキストをどのように伸縮させるかを指定しています。

ここで使っているflexはFlexboxプロパティ(flex-grow, flex-shrink, flex-basis)のショートハンドになります。

ここで、このショートハンドの説明をするとそれだけで一記事できてしまうほどのボリュームになってしまいますので、参考記事をご紹介するだけにとどめておきます。

今回の例ですと、

  • 画像:flex-grow:0, flex-shrink: 1, flex-basis: 30%
  • テキスト:flex:1(flex-grow:1, flex-shrink:1, flex-basis: 0と同等)

と指定しているので、スクリーンサイズが変化したときの動きをざっくり表現すると、以下のような感じになります。

  • 画像:スクリーンサイズが変化しても、親要素の幅の30%を常に維持する。
  • テキスト:親要素の幅から画像と余白を除き、残った領域はすべて総取りする。

画像は小さくなりすぎると見づらくなるので、flex-basisで最小幅を決めて、テキストは余ったエリアで表示させている、ということですね。

③margin-right: 3%;

親要素の幅の3%を、画像とテキストの余白に当てています。

余白を固定値(px)で指定すると、スクリーンサイズが縮んだときに、余白が相対的に広くなって、全体のバランスが崩れます。

そのために固定値(px)ではなく、相対値(%)で指定しています。

④width: 100%;

スクリーンサイズが狭いとき、画像が親要素(この場合は.media__img-wrapper)からはみ出さないようにするための指定です。この指定は、結構忘れがちです・・・。

⑤margin-bottom: 0;

将来の保守のことを考えた、実は格調高いコードです。

この指定は、.media__bodyの最後の子要素の下部余白を削除しています。

今回のコードでは、最後の子要素<p>に下部余白を設定していないので、直接影響はない指定ですが、今後、子要素を追加/削除したときに効果を発揮します。

例として、最後の子要素<p>を削除し、タイトルだけ残す場合を考えてみます。

margin-bottom: 0;が適用されていない場合、下記のようにタイトル下部にmarginが残っているので、タイトルが天地中央からやや上寄りにずれてしまいます。

一方、margin-bottom: 0;を適用しておくと、タイトル下部のmarginが削除され、ぴったり天地中央に揃います。

このように、複数の要素からなるパーツの場合、最後の要素の下部余白を常に削除する設定にしておくと、レイアウト崩れが起きなくなるので、覚えておくと便利です。

⑥display: block;

メディアクエリ適用時には、画像を上、テキストを下に並び替えるため、display: block;でFlexboxを解除します。(または、Flexboxは解除せずにflex-direction: columnを追加してもOK)

⑦margin-right: 0; / margin-bottom: 20px;

横並びのときに指定されていた画像右側の余白を、縦並びに合わせて画像下部に付け替えています。

おわり

メディアはコーポレートサイトなどでよく出てくるパーツなので、使いまわしできるコードを一つ常備しておくと、とても便利ですね。この機会にぜひ自在に使えるようにしてみてください。

次回はこれを基本として、拡張バージョンを作ってみたいと思います。

なお、この記事は以下の書籍を参考にさせていただいてます。CSS設計を体系的に学ぶには最高の一冊です。

この記事を書いた人

ホリエ

新卒で大企業に入社。16年後に「そうだ、これからは個人で生きていこう」と思いたち、フリーランスになった人。
Web制作を中心にこつこつモノづくりの日々を送っています。