CSSの基本的な文法を理解していれば、デザイン通りの画面は作成できます。
しかし何も考えずに実装をすると、拡張性がなかったりメンテナスしにくかったりするCSSとなってしまいます。
「よいCSS設計」には以下の4つの特徴があります。1
- 予測できる
- 再利用できる
- 保守できる
- 拡張できる
特にWebサービスのように複数画面のあるサイトのCSSを作成する場合は、再利用しやすい形でCSS設計をしておくことで効率的に開発ができますし、Webサイトのデザインの統一感も図れます。
今回はよいCSS設計にするためのCSS実装手順について具体例をもとに紹介します。
目次
今回実装するデザインについて
今回は、ランディングページなどでよく見かける『横並びのカードレイアウト』を具体例として利用します。
以下のように、3つの料金表が並んだデザインの実装をゴールにします。
CSS設計の手順
CSS設計の手順は以下の通りです。
- デザインを『レイアウト』と『UIパーツ』に分類する
- 分類した要素ごとにCSSの実装をする
- レイアウトにUIパーツを組み込む
以下ではそれぞれの手順について紹介していきます。
デザインを『レイアウト』と『UIパーツ』分類する
CSS設計をする上で重要なのが、デザインの構成要素を『レイアウト』と『UIパーツ』に分類することです。
レイアウトとUIパーツのCSSを同じクラスに混在させないことでUIパーツの使い回しが容易になるため、管理がしやすいCSS設計となります。
今回の例をレイアウトとUIパーツに分ける場合、以下の3つの要素に分類できます。
- 料金エリアのレイアウト(画面全体のレイアウト)
- 料金表のレイアウト(UIパーツ同士のレイアウト)
- 『料金表』というUIパーツ
分類した要素ごとにCSSの実装をする
レイアウトとUIパーツごとにHTML・CSSを実装します。
なお、今回のCSS設計では手法にBEMを採用します。
料金エリアのレイアウト(画面全体のレイアウト)
料金エリア(ピンク色の部分)はヘッダ(水色の部分)とボディ(緑色の部分)で構成されています。
BEMで表現すると、エリアがblock、ヘッダとボディがelementとなります。
画面全体のレイアウトに関するHTMLとCSSは以下の通りです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/css-wipe/reset.css" />
<link href="css/price-area-layout-hoge.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="price-area">
<h2 class="price-area__header">
price-area__header
</h2>
<div class="price-area__body">
price-area__body
</div>
</div>
</body>
</html>
/* ------------------------------
price-area
------------------------------ */
.price-area {
background-color: lightcoral;
padding: 15px 30px;
width: 1080px;
max-width: 100%;
margin: 0 auto;
}
.price-area__header {
background-color: lightblue;
font-size: 35px;
margin-bottom: 20px;
padding: 10px 0px;
border-bottom: 1px solid #ddd;
}
.price-area__body {
background-color: lightgreen;
}
料金表のレイアウト(UIパーツ同士のレイアウト)
料金表が3つ横並びになっているので、横並びのレイアウトに関するCSS設計をします。
料金表のレイアウト(ピンク色の部分)は3つの料金表(水色の部分)で構成されています。
BEMで表現すると、料金表を配置する箇所がblock、料金表がelementとなります。
料金表のレイアウトに関するHTMLとCSSは以下の通りです。
今回はflexboxを利用してブロック要素(料金表)を横並びにしました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/css-wipe/reset.css" />
<link href="css/price-box-layout-hoge.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="price-boxes">
<div class="price-boxes__item">
price-boxes__item
</div>
<div class="price-boxes__item">
price-boxes__item
</div>
<div class="price-boxes__item">
price-boxes__item
</div>
</div>
</body>
</html>
/* ------------------------------
price-boxes
------------------------------ */
.price-boxes {
background-color: lightcoral;
display: flex;
align-items: flex-start;
justify-content: center;
}
.price-boxes__item {
background-color: lightblue;
flex: 1;
margin-right: 2.43902%;
}
.price-boxes__item:last-child {
margin-right: 0;
}
『料金表』というUIパーツ
料金表はヘッダ(水色の部分)、タイトル(緑色の部分)、ボディ(灰色の部分)、価格表示(ピンク色の部分)、説明文(黄色の部分)で構成されています。
料金表のHTMLとCSSは以下の通りです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/css-wipe/reset.css" />
<link href="css/price-box-hoge.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="price-box">
<div class="price-box__header">
<div class="price-box__title">price-box__title</div>
</div>
<div class="price-box__body">
<p class="price-box__price">price-box__price</p>
<p class="price-box__description">price-box__description</p>
</div>
</div>
</body>
</html>
/* ------------------------------
price-box
------------------------------ */
.price-box {
background-color: lightcoral;
border: 1px solid #ddd;
}
.price-box__header {
background-color: lightblue;
padding: 30px 15px;
border-bottom: 1px solid #ddd;
}
.price-box__title {
background-color: lightgreen;
font-size: 20px;
font-weight: bold;
}
.price-box__body {
background-color: lightgrey;
padding: 40px 15px;
}
.price-box__price {
background-color: lightpink;
font-size: 18px;
font-weight: bold;
margin-bottom: 25px;
}
.price-box__description {
background-color: lightyellow;
}
UIパーツのCSS設計では、UIパーツを使い回しのしやすい形にすることが重要です。
具体的には、UIパーツの外に作用するCSS(marginなど)はUIパーツのCSSで定義しないようにします。
marginをUIパーツのCSSに定義しないことでレイアウトの中にUIパーツがぴったり埋め込まれる形になるため、UIパーツの再利用性が高まります。
デザインのどの箇所をUIパーツとして定義したらよいか分からない場合は「デザインを使い回すとしたらどういった単位(パーツ)になるのか」を考えるとUIパーツを見つけやすいです。
レイアウトにUIパーツを組み込む
レイアウトとUIパーツを作成できたら、それぞれのHTML・CSSを組み合わせます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/css-wipe/reset.css" />
<link href="css/simple-price-boxes.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="price-area">
<h2 class="price-area__header">
料金一覧
</h2>
<div class="price-area__body">
<div class="price-boxes">
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">FREE</div>
</div>
<div class="price-box__body">
<p class="price-box__price">無料</p>
<p class="price-box__description">無料で使えるプランです。料金を気にせずサービスを利用できます。</p>
</div>
</div>
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">STANDARD</div>
</div>
<div class="price-box__body">
<p class="price-box__price">1,000円/月</p>
<p class="price-box__description">一般的なプランです。お手頃な価格でサービスを利用できます。</p>
</div>
</div>
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">PRO</div>
</div>
<div class="price-box__body">
<p class="price-box__price">3,000円/月</p>
<p class="price-box__description">フルスペックのプランです。サービスの全ての機能を利用できます。</p>
</div>
</div>
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">PRO+</div>
</div>
<div class="price-box__body">
<p class="price-box__price">10,000円/月</p>
<p class="price-box__description">新しく追加されたフルスペックのプランです。個別サポートにも対応しております。</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
/* ------------------------------
price-area
------------------------------ */
.price-area {
padding: 15px 30px;
width: 1080px;
max-width: 100%;
margin: 0 auto;
}
.price-area__header {
font-size: 35px;
margin-bottom: 20px;
padding: 10px 0px;
border-bottom: 1px solid #ddd;
}
.price-area__body {
}
/* ------------------------------
price-boxes
------------------------------ */
.price-boxes {
display: flex;
align-items: flex-start;
justify-content: center;
}
.price-boxes__item {
flex: 1;
margin-right: 2.43902%;
}
.price-boxes__item:last-child {
margin-right: 0;
}
/* ------------------------------
price-box
------------------------------ */
.price-box {
border: 1px solid #ddd;
}
.price-box__header {
padding: 30px 15px;
border-bottom: 1px solid #ddd;
}
.price-box__title {
font-size: 20px;
font-weight: bold;
}
.price-box__body {
padding: 40px 15px;
}
.price-box__price {
font-size: 18px;
font-weight: bold;
margin-bottom: 25px;
}
.price-box__description {
}
すべて組み合わせると以下のようになります。
参考: UIパーツを再利用してみる
たとえば、料金表のデザインを横3列から4列に変更するとします。
その場合、UIパーツを追加するだけで横4列のデザインが完成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/css-wipe/reset.css" />
<link href="css/simple-price-boxes.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="price-area">
<h2 class="price-area__header">
料金一覧
</h2>
<div class="price-area__body">
<div class="price-boxes">
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">FREE</div>
</div>
<div class="price-box__body">
<p class="price-box__price">無料</p>
<p class="price-box__description">無料で使えるプランです。料金を気にせずサービスを利用できます。</p>
</div>
</div>
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">STANDARD</div>
</div>
<div class="price-box__body">
<p class="price-box__price">1,000円/月</p>
<p class="price-box__description">一般的なプランです。お手頃な価格でサービスを利用できます。</p>
</div>
</div>
<div class="price-boxes__item price-box">
<div class="price-box__header">
<div class="price-box__title">PRO</div>
</div>
<div class="price-box__body">
<p class="price-box__price">3,000円/月</p>
<p class="price-box__description">フルスペックのプランです。サービスの全ての機能を利用できます。</p>
</div>
</div>
+ <div class="price-boxes__item price-box">
+ <div class="price-box__header">
+ <div class="price-box__title">PRO+</div>
+ </div>
+ <div class="price-box__body">
+ <p class="price-box__price">10,000円/月</p>
+ <p class="price-box__description">新しく追加されたフルスペックのプランです。個別サポートにも対応しております。</p>
+ </div>
+ </div>
</div>
</div>
</div>
</body>
</html>
このように、使い回しのしやすいUIパーツを作成することで拡張性の高いCSSになっていることがわかります。
まとめ
- デザインをレイアウトとUIパーツに分類する
- UIパーツのCSSは再利用しやすい形に設計する
- レイアウトとUIパーツのCSSは同じクラスに混在させない
「デザインをもとにHTML/CSSの実装はできるけど、正しい実装なのか自信がない」「巷で人気のHTML/CSS本だと内容が初心者向きすぎて物足りない」といった方は『CSS設計』というキーワードをもとに参考書を探すとよいでしょう。
個人的には、CSS設計の参考書はCSS設計完全ガイド ~詳細解説+実践的モジュール集
がオススメです。
自分はバックエンドメインで仕事をしてきたので、CSS設計については自信がなかったのですが、CSS設計完全ガイド ~詳細解説+実践的モジュール集のおかげでマークアップに対する苦手意識を克服できました。
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!