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

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

まだ前回の解説を読んでいない方は、ぜひそちらからお読みください。

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

今回は、ページ全体で使う共通パーツと、お問い合わせフォームについて解説していきます。

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

工程その4 ページ全体で共通のパーツを探す

前回の記事では最後の方で「共通の横幅を定義づける.common-inner」というパーツだけ取り上げましたが、実はこのページには他にも共通の箇所があります。

上の画像にある

  • 各セクションの上下の余白
  • 各セクションのタイトル
  • 角丸のボタン

については共通パーツとして作れそうですね。

工程その5 共通パーツ「セクションの上下の余白」作る

こちらはシンプルに上下の余白をもたせるだけのスタイルを定義しておきましょう。

.section {
  padding: 100px 0;
}

デザインを見るとセクションによっては水色の背景色が設定されている箇所がありますが、こういった変化についてはいくつかのアプローチがあります。

  • クラス名を.section–lightblueと設定し、BEMのModifierのような考え方で拡張する。
  • OOCSS(※1)のアプローチで背景色を水色にするだけの.background-lightblueのようなクラスを付与する。
  • main要素直下のsection要素に対する:nth-child(even)擬似クラスを用いて背景色を設定する。
  • 各セクションに個別のidやクラス名を付与し、そこに背景色を設定する。

これらはどれを使っても間違いではありませんが、Webサイトの規模や関わるメンバーによって何が最適かを見極めることが重要です。
今回は各セクションに個別のidを割り振り、そちらで設定することにします。


※1:「Object Oriented CSS(オブジェクト指向CSS)」の略で、米Yahoo!の開発者であるNicole Sullivanが提唱したCSSの設計手法

工程その6 共通パーツ「セクションのタイトル」作る

ここは以下のようにマークアップしてみました。
各セクションに紐づくタイトルなので.section__titleというクラス名にします。

<h2 class="section__title typo-bold"><span>セクションタイトル</span></h2>

一見すると入れ子になっているspan要素は必要ないと思えるかもしれませんが、後々これが非常に重要な役割を果たします。

フォントスタイルとマージンを設定する

まずは文字自体の大きさや、タイトルの後に来る要素との余白を設定しましょう。

.section__title {
  margin-bottom: 50px;
  font-size: 3.2rem;
  line-height: 1.0;
}

青三角形の「あしらい」を作る

次に左上と右下にある青い三角形のあしらいをつけましょう。
これはspanに対する疑似要素として作り、それを絶対配置で左上と右下それぞれに置くことで実現します。

.section__title span {
  /* 文字数によって横幅が変化するので幅指定は絶対にしない */
  display: inline-block;
  padding: 10px 22px;
  position: relative;
}

.section__title span:before, .section__title span:after {
  content: '';
  display: block;
  width: 16px;
  height: 16px;
  position: absolute;
  z-index: 1;
}

.section__title span:before {
  top: 0;
  left: 0;
  /*
    右下に向かって斜めにグラデーションをかける
    開始位置から50%までは青色
    50%から終了位置までは透明
  */
  background: linear-gradient(135deg, #008dd5 0%, #008dd5 50%, transparent 50%, transparent 100%);
}

.section__title span:after {
  right: 0;
  bottom: 0;
 /*
    右下に向かって斜めにグラデーションをかける
    開始位置から50%までは透明
    50%から終了位置までは青色
  */
  background: linear-gradient(135deg, transparent 0%, transparent 50%, #008dd5 50%, #008dd5 100%);
}

ここで重要なポイントが2点あります。

1.display: inline-blockで幅を可変にする。
この見出しはセクションによって内容が異なるため、固定幅を指定することはできません。
しかし、三角形のあしらいは必ず文字要素の左右に配置されています。
そこでspan要素自体にdisplay: inline-blockを指定することで、文字数に応じた横幅になるよう設定しています。

2.あしらいは疑似要素でつくる
左上と右下についているあしらいは、span要素に対する疑似要素として作ります。
この時に使えるテクニックがlinear-gradientプロパティ、つまりCSSによるグラデーションです。
グラデーションというと徐々に色が変わっていく表現が一般的ですが、CSSでは今回のように「ある部分を境にバッサリ色を変える」ということができます。
それを応用することで、今回のように斜め半分だけ色をつけるということができるわけですね。

この内容をブラウザで確認すると以下のようになっていると思います。

それっぽくなりましたね!

中央寄せにする span要素の謎を解明…!?

さて、あとはこれをセンタリングするだけです。
ここでまさに一見不要と思われたspan要素が生きてきます。
span要素の親要素である.section__titleにスタイルを一行追加しましょう。

.section__title {
  margin-bottom: 50px;
  font-size: 3.2rem;
  line-height: 1.0;
  text-align: center; /* ←追加 */
}

display: inline-blockを指定した要素にmargin: autoは適用できません。
そのため、親要素であるh2にtext-align: centerを指定することで、センタリングを実現しています。

工程その7 共通パーツ「角丸のボタン」作る

最後に角丸のボタンを作りましょう。
ちょっと複雑そうに見えますが、実はHTMLの記述自体は以下の一行だけです。

<a href="#" class="primary-button typo-bold">機能について詳しく知る</a>

その代わり、CSSの方がちょっと複雑になります。
気合入れていきましょう。

まずはベースとなる形を作る

.primary-button {
  /* 文字要素を天地中央にする */
  display: flex;
  justify-content: center;
  align-items: center;

  /* "最小"幅として設定することで長い文字列が入ってきても対応できる! */
  min-width: 280px;
  /* 中身がどんなに長くなっても最低20pxは左右に余白ができるようにする */
  padding: 0 20px;
  box-sizing: border-box;

  /* ボタンなので複数行は考慮せず高さは固定値 */
  height: 60px;
  font-size: 1.6rem;
  color: #008DD5;
  background-color: #fff;
  border: 1px solid #008DD5;
  border-radius: 4px;
  position: relative;
  transition: 0.2s ease 0s;
  transition-property: background-color, color;
}

/* セクションの見出しと同様、疑似要素であしらいを置く */
.primary-button::before {
  content: '';
  display: block;
  width: 10px;
  height: 10px;
  position: absolute;
  right: 5px;
  bottom: 5px;
  z-index: 1;
}

.primary-button::before {
  background: linear-gradient(135deg, transparent 0%, transparent 50%, #008DD5 50%, #008DD5 100%);
}

れっきとしたボタンになりましたね!

マウスオン時のスタイルを設定する

ボタンっぽくはなりましたが、先ほどの状態ではちょっと寂しいので、ボタンにマウスオンした時に

こんな風に変化するようにしましょう。
バリバリCSSを追記していきます!

/* 先ほど設定したbefore疑似要素に加え、同じスタイルを持ったafter疑似要素を作る */
.primary-button::before,
.primary-button::after /* ←追加 */ {
  ...
}

.primary-button::before {
  background: linear-gradient(135deg, transparent 0%, transparent 50%, #008DD5 50%, #008DD5 100%);
  opacity: 1; /* ←追加 */
}

/* after疑似要素にも色を変えて(白)グラデーションを設定 */
.primary-button::after {
  background: linear-gradient(135deg, transparent 0%, transparent 50%, #fff 50%, #fff 100%);
  opacity: 0; /* ←opacityを0にしておくことで、見えない状態にする */
}
/* ボタン自体にマウスオンした時に背景色と文字色を切り替える設定を追加する */
.primary-button:hover {
  background-color: #008DD5;
  color: #fff;
}

/* マウスオンされた時に青色三角のbefore疑似要素は不透明度が0になる(見えなくなる) */
.primary-button:hover::before {
  opacity: 0;
}

/* マウスオンされた時に白色三角のbefore疑似要素は不透明度が1になる(見えるようになる) */
.primary-button:hover::after {
  opacity: 1;
}

疑似要素の「あしらい」についてはちょっとややこしいですが、ひとつずつ紐解くと実は非常に簡単な原理で動いています。

まず同じ形で色違いのあしらいパーツをbefore疑似要素とafter疑似要素で作り、position: absoluteで同じ位置に配置します。
そしてそれぞれの不透明度を、どちらかは1、どちらかで設定し、片方だけ見えている状態にします。
あとは.primary-buttonにマウスオンしたときに不透明度の1と0を逆転させ、先ほどまで見えていた方を見えなくし、逆に見えていなかった方を見えるようにしています。

さて、ここで勘の鋭い方はあることに気づいたかもしれません。
「わざわざ疑似要素を2個使わなくても、linear-gradientの色を変えればいいだけじゃ…?」
全くその通りです。でも実はその実装だと不都合な場合があります。

トランジションを設定しふわっと変える

先に述べた「不都合」の正体が、CSSトランジションです。
先ほどの実装でマウスオンした時にボタンの色を変えることには成功しましたが、パッと変わるよりふわっと変わった方がより自然な表現になります。
Mozzilaによると、linear-gradientはCSSの型、つまり画像として扱われるので、CSSトランジションが効きません。
それなので、色違いの要素を用意して、それぞれの可視状態を切り替えることで擬似的に色が変わったように見せているわけです。

それでは以下のコードを追記してみましょう。

.primary-button {
  ...
  /* ↓追記 */
  transition: 0.2s ease 0s;
  transition-property: background-color, color;
}

.primary-button::before,
.primary-button::after {
  ...
  transition: opacity 0.2s ease 0s; /* ←追記 */
}

このパターンは実務でも非常によく使われています。
疑似要素でなく画像で色違いのアイコンを切り替える際にも使ったりするので、ぜひマスターしましょう。

白黒バージョンを最小限のコードで作る

さて、ボタンの基本形が完成したので同じ形で色違いのパターンを作りましょう。

ここではBEMModifierという考え方で実装してみようと思います。
まずは先ほど作ったボタンに「.primary-button–monochrome」というクラス名を追加しましょう。

<a class="primary-button primary-button--monochrome typo-bold">送信</a>

そして以下のCSSを追記して拡張します。

/* ボタンの文字色と背景色を黒にする */
.primary-button--monochrome {
  color: #333;
  border-color: #333;
}


/* マウスオンした時の背景色も忘れずに */
.primary-button--monochrome:hover {
  background-color: #333;
}


/* 「あしらい」の色も忘れずに */
.primary-button--monochrome::before {
  background: linear-gradient(135deg, transparent 0%, transparent 50%, #333 50%, #333 100%);
}

終わりです。
たったこれだけで別パターンのボタンを作ることができました。
今回は単純にマルチクラスを用いてスタイルを拡張する方法を取りましたが、属性セレクタを用いる方法や、Sassと組み合わせて継承を使ってシングルクラスで実現する方法もあります。

まとめ

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

  • 文字数に応じて横幅を可変させたいときはinline-blockを使う
  • linear-gradientの使い方はグラデーション表現だけではない
  • パターン違いのパーツについてはBEMのModifierが使えないか検討する

次回はメインコンテンツ部分を解説します。

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

関連記事