【初心者向け】HTML+CSSの練習に最適!KROWLコーディング課題「ツールの紹介サイト」 – 解説編 その3

本記事では前回に続き、HTML / CSSの練習用にKROWLサイトで配布している、KROWLコーディング課題「ツールの紹介サイト」のコード解説をしていきたいと思います。

まだ「その1」「その2」を読んでいない方は、ぜひそちらからお読みください。

ぜひKROWLサイトから課題をダウンロードし、同梱されているサンプルコードを見ながらお読みください!

前回まででヘッダー、フッター、ページ全体で使う共通パーツを作りました。
今回は、いよいよメインコンテンツエリアを進めていきます。

※本記事に掲載されているコードはあくまでも一例です。絶対的な正解というわけではありませんので、予めご了承ください。

工程その8 「最新情報」セクションを実装する

「最新情報」というだけあって、ここは常日頃から更新されているという背景が考えられます。
そこで、実装レベルでは以下のことについて考えておく必要があります。

  • デザイン上では最大2行だが、それ以上の行数になるかもしれない。
  • 掲載するニュースが1件だけのこともあるかもしれない。
  • 掲載するニュースが3件以下になり、「過去の情報を見る」というリンク自体が不要になるかもしれない。

以前の記事やKROWLイベントでもお伝えしていますが、マークアップという作業はこういった「デザインを見ただけではわからない”かもしれない”」を考えることがとても重要です。

それでは実際に書いていきましょう。
今回は以下のようにhtmlを記述しました。

<!-- メインコンテンツ -->
<main>
  <!-- 最新情報 -->
  <section id="news" class="section">
    <div class="common-inner">
      <h2 class="section__title typo-bold"><span>最新情報</span></h2>
      <ul class="news-list">
        <li class="news-list__item"><a href="#"><time datetime="2019-08-23">2019.08.23</time><span>新料金プラン「Mania 5」をリリースしました</span></a></li>
        ...省略...
      </ul>
      <p class="news-page-link"><a href="#" class="typo-bold">過去の情報を見る</a></p>
    </div>
  </section>
  <!-- 最新情報 -->
</main>
<!-- メインコンテンツ -->

それではスタイルをあてていきましょう。

.news-list {
 width: 640px;
}

/* :not(:last-child)パターンを使うことで、「過去の〜」リンクがあるときだけmargin-bottomがつくようにする */
.news-list:not(:last-child) {
 margin: 0 auto 50px;
}

/* 子要素である.news-list__itemも親同様:not(:last-child)パターンでmargin-bottomを設定する */
.news-list__item:not(:last-child) {
 margin-bottom: 20px;
}

.news-list__item a {
 /* 日付と見出しは横並びなのでFlexboxを使う */
 display: flex;
 justify-content: space-between;

 font-size: 1.6rem;
 line-height: 1.75;
 color: #000;
}

.news-list__item a:hover {
 text-decoration: underline;
}

.news-list__item a span {
 width: 470px;
}

/* 過去の情報を見る */
.news-page-link {
 text-align: center;
}

.news-page-link a {
 font-size: 1.6rem;
 color: #008DD5;
}

.news-page-link a:hover {
 text-decoration: underline;
}

先に挙げた「かもしれない」を考慮し、「安易に高さを設定しない」や「:not(:last-child)パターンを使って、兄弟要素がなかった場合にも備える」といったスタイリングを心がけるようにしましょう。

工程その9 「サービスの特長」セクションを実装する

まずはこのセクション全体のHTMLを見てみましょう。

<section id="feature" class="section">
  <div class="common-inner">
    <h2 class="section__title typo-bold"><span>サービスの特長</span></h2>
    <div class="feature-block">
      <p class="feature-block__text">DataManiaはデータマーケティングの効率を最大化するために設計されています。<br>自動分析・レポート機能、ユーザー管理機能、通知機能、その他データマーケティングに必要不可欠な40の機能を、先進的で洗練されたインターフェースで利用することができます。<br>満を持してリリースされたバージョン2からは、忙しいマーケターのためにスマートフォンアプリ版もリリースされました。</p>
      <ul class="feature-block__icons feature-icon-list">
        <li class="feature-icon-list__item"><img src="assets/images/icon-auto_reporting.png" alt="自動分析機能のアイコン"></li>
        ...省略...
      </ul>
      <p class="feature-block__button"><a href="#" class="primary-button typo-bold">機能について詳しく知る</a></p>
    </div>
  </div>
</section>

どうやらそんなに複雑な構造はしていないようですね。
まずはこのセクション自体に水色の背景色を設定してしまいましょう。

#feature {
 background-color: #E6F6FF;
}

.feature-blockの大枠を作っていく

次に「テキスト」「アイコン類」「ボタン」が内包されている白背景のブロックにスタイルをあてていきます。

.feature-block {
  display: flex;
  /* ↓重要!↓ */
  flex-wrap: wrap;
  justify-content: center;

  /* 余白の部分は自身のpaddingとして持っておく */
  padding: 60px;
  background-color: #fff;
}

.feature-block__text {
  width: 460px;
  margin-right: 60px;
  font-size: 1.6rem;
  line-height: 1.75;
}

.feature-block__button {
  margin-top: 40px;
}

.feature-icon-list {
  width: 360px;
}

ここで一番重要なのが

  • flex-wrap: wrap
  • justify-content: center

です。

Flexboxを使うと、通常はその子要素が全て横並びになります。
ですが、今回はボタンだけ他のふたつの要素の下に配置されています。
そこで、.feature-block自体にflex-wrap: wrapを設定することでこのレイアウトを実現しました。図で解説してみましょう。

まず一番外側は.common-innerによって1000pxの幅に設定されます。
次に.feature-block自身のpaddingによって、実際にコンテンツが入り込める余地は1000px – (60px * 2) = 880pxになります。
そしてそこからテキストの横幅である460pxとマージンの60px、そしてアイコン類の横幅である360pxを引くと…

880px – 460px – 60px – 360px = 0

見事にボタンの入る余地がなくなってしまいました。
そこで仕方なくテキストやアイコン類の下に配置されますが、その際に.feature-blockjustify-content: centerによって中央寄せされます。
Flexboxを利用したテクニックのひとつとして、是非習得しておきたいですね。

アイコンを整理する

先ほど解説で使った画像ではきちんとデザイン通りに実装されていましたが、今の段階で実際にブラウザで確認すると、以下のようになっていると思います。

このアイコンが縦並びの状態を直し、きちんと整理することにしましょう。

.feature-icon-list {
  /* ↓追加 */
  display: flex;
  flex-wrap: wrap;
  
  width: 360px;
}

/* 2段目の最後のアイコン以外は全て右方向に40pxの余白を設ける */
.feature-icon-list__item:not(:last-child) {
  margin-right: 40px;
}

/* 最初から数えて3番目までのアイコンには下方向に20pxの余白を設ける */
.feature-icon-list__item:nth-child(-n+3) {
  margin-bottom: 20px;
}

/* 2段目の最初のアイコンには左方向に40pxの余白を設ける */
.feature-icon-list__item:nth-child(4) {
  margin-left: 40px;
}

ここも横並びで、かつ4個目以降のアイコンは2段目に折り返しているので、先ほど同様flex-wrap: wrapを用いたFlexboxで実装します。
さらにここは:nth-childを多用してそれぞれのアイコンの間隔を調整しましょう。

工程その10「Data Maniaの3つの強み」セクションを実装する

こちらも最初にhtml構造を見ていきましょう。

<!-- Data Maniaの3つの強み -->
<section id="advantage" class="section">
  <div class="common-inner">
    <h2 class="section__title typo-bold"><span>Data Maniaの3つの強み</span></h2>
    <ol class="advantage-list">
      <li class="advantage-list__item advantage-block">
        <div class="advantage-block__image"><img src="assets/images/img-usp-01.jpg" alt="Data Maniaアプリケーションの一部"></div>
        <div class="advantage-block__inner">
          <h3 class="advantage-block__title typo-bold">データマーケティングの支援に特化</h3>
          <p class="advantage-block__text">データ分析アプリケーションは多数ありますが、データマーケティングに特化したものはData Maniaを置いて他にありません。単なる分析機能・レポーティング機能だけでなく、当社独自調査による過去のマーケティング事例を元に、最適な施策を提案します。</p>
        </div>
      </li>
      ...省略...
    </ol>
  </div>
</section>
<!-- Data Maniaの3つの強み -->

このセクションでユニークになる要素として、.advantage-list.advantage-blockというふたつのかたまり(BEMで言うところのBlock)を用意しました。
まずは.advantage-blockを実装していきましょう。

天地中央寄せを実現する

デザインを見ると、「画像+見出し&テキスト」のブロックで構成されていることがわかります。
ここで注目したいのが、それぞれの縦方向の位置関係です。

例によって「見えない線」を意識してみると、「画像」と「見出し+テキストのブロック」は「縦方向の中心線が揃っている(天地中央揃え)」ということが見て取れます。
これを実現するために、Flexboxのalign-items: centerを使います。

.advantage-block {
 display: flex;
 /* 子要素を天地中央で揃える */
 align-items: center;
}
/* 画像は固定の幅・高さを持たせる */
.advantage-block__image {
 width: 300px;
 height: 300px;
 margin-right: 40px;
}
/* 見出し+テキストのブロックの横幅は「残りの幅(100% - 300px)」になるように伸縮させる */
.advantage-block__inner {
 flex: 1;
}

ブラウザで確認してみると以下のようになると思います。

きちんと天地中央揃えになってますね。

画像を円で切り取る

デザインデータを見ると、画像を円形のオブジェクトでマスクしています。
これを実現するために、円形の透過pngで書き出したりPhotoshopなどで丸く加工する手段もありますが、CSSでも同様のことができるので、今回はCSSでやってみましょう。
基本的な考え方は以下のようになります。

.advantage-block__image {
 width: 300px;
 height: 300px;
 margin-right: 40px;
 /* ↓追加↓ */
 /* パーセントで指定しておくことで画像の大きさが変わっても再計算する必要がない */
 border-radius: 50%;
 /* border-radiusによってはみ出した部分を非表示にする */
 overflow: hidden;
}

見出し+テキストのブロックを作る

次に見出しとテキストのブロックを実装しましょう。

.advantage-block__title {
 margin-bottom: 20px;
 font-size: 2.4rem;
 line-height: 1.5;
 border-bottom: 2px solid #008DD5;
}

.advantage-block__text {
 font-size: 1.6rem;
 line-height: 2;
}

といっても特に難しいことはありませんでしたね!

見出しの数字は?

ところがここでひとつ足りないものがあります。
そう、見出しの先頭の数字です。
単純に文字要素として入れてしまっても良いのですが、今回はこれをあえてCSSで入れることにしましょう。

.advantage-list {
 /* advantage-counterというカウンターをリセットする */
 counter-reset: advantage-counter;
 /* この時点でのカウンター値「0」 */
}

.advantage-list .advantage-block__title:before {
 /* この時点でのカウンタ値ー「0」 */
 /* advantage-counterのカウントを増やす */
 counter-increment: advantage-counter;
 /* この時点でのカウンタ値ー「1」 */
 content: counter(advantage-counter) ". ";
}

あまり見慣れない方もいらっしゃると思いますが、今回はCSSのカウンターを使ってみました。
CSSのカウンターはcounter-resetcounter-incrementというプロパティでカウンターの値を操作し、counter(カウンター識別子)というバリューでカウンターの値を利用します。
何を言っているのかわからないと思うので画像で解説します。

今回の例ではそこまでの必要性を感じませんが、「規則的に順番をつける必要があるけど数が不明・よく変わる」といった場面で活躍します。

また、「n番目」という概念自体が「リストとして存在している」ということに依存するので、あえて「.advantage-listの子要素の.advantage-block__title:before」という形で指定しています。

仕上げ

さて、最後にそれぞれの余白を設定してあげれば完了です。

.advantage-list__item:not(:last-child) {
 margin-bottom: 50px;
}

できました!
覚えることがたくさんあって大変な箇所でしたが、どれも実務で頻出するパターンなので、きちんと理解しておきましょう。

まとめ

今回のポイントはこちらです。

  • 「かもしれない」実装を心がける
  • flex-wrapを理解して変則的な横並びをマスターする
  • border-radiusとoverflow: hiddenの組み合わせで画像加工せずに画像の見せ方を変える
  • 規則的に変化する数字についてはcounter-increment, counter-resetを使う手もあり

次回はいよいよこのシリーズの完結編です。あと一息がんばりましょう!

HTMLやCSS、JavaScriptの学習をしている方に向けて無料のコーディング課題をKROWLサイトで配布中!
難易度別に用意してあるサンプルサイトのデザインデータを元に、サイト制作のスキルを磨こう!

関連記事