はじめに
谷拓樹さんのWEB制作者のためのCSS設計の教科書を読み、自分なりにまとめたものです。
自分のメモとして残しておきたいので、詳細を多少端折っていますので、気になる方は購入してみてください。
数回に分けて投稿する予定です。
コンポーネント設計の実践
コンポーネントをどのように作るか
ここの章では、コンポーネント化を進めていこう、と考えたとして
「どのようにすすめるのか」、「コンポーネントにする粒度は(再利用を考える目安)」という問題に直面するはずである。しかしこれらの疑問に対する答えはたった一つ、**「時と場合による」**ということである。
あらゆる問題に対する答えは残念ながらないが、問題に対するヒントやアイデアをここから紹介していく。
最適化を焦らない
コンポーネント設計がフォーカスするのは、そのコンポーネントのメンテナンス性と再利用性である。
その為最初からそのことに意識してしまうと、すべての要素に対して再利用することを考えてしまう。
しかし実際には、はじめからあらゆる場面で再利用できるようなコンポーネントを作ることは不可能に近い。
コンポーネント設計でハマりがちなのは、プロジェクトの初期段階で「これも後で使いそうなので、汎用的なものにしておこう」と時間をかけて作ったものが、その後に使わずに無駄になってしまうということである。
Rule of three
Refactoringという書籍の中で紹介されている。
結論を完結に言えば、「3回繰り返したものは、パターンとして成立する」ということである。
3,6…………..
3と6という二つの数字があったとき、その次に続く数字は何でしょう。
3,6,9,12,15…..
と3の倍数が続くと考える人もいれば、あるいは
3,6,12,24,48
と倍になっていくと考える人もいるかもしれない。しかし、
3,6,9…...
と3つの数字がわかれば、次の数字は12になる確立が高くなる。これをコンポーネント化のプロセスに応用すれば、次のような考え方ができる。
- 初めてそのパターンが登場した時は、再利用することは特に考えない
- 一度解決したパターンに再び出会ったとしても、コンポーネント化したい気持ちを抑える
- 3度目になって、パターンとして何がわかっていて、何がわかっていないかを考えてコンポーネント化する為にリファクタリングする。
理論的にも3回を目安にすることでリファクタリングするタイミングを逃す事無く、コンポーネント化が進めやすくなる。
タイミングを失って後回しにしすぎてしまうと、影響範囲が大きすぎて手を出しづらくなってしまうことがある。
そうした修復が不可能と言えるようなレベルになってしまったとき、最悪で最善な対処法は、全てを書き直すということになってしまう。(冗談のような、本当の話。)
そうならないためにも、早めにリファクタリングを行うことは大切であり、これまでに解説した**「詳細度の高いセレクタを書かない」** **「クラス名の衝突・スタイルの汚染がないようなユニークなクラス名をつける」**といったことを心がけるようにすべきである。
Rule of threeを別の視点で捉えれば、「そのコンポーネントが、3つのプロジェクトで使えたならば、他のプロジェクトでも利用できる可能性がある」
SOLID CSS
CSSに限らず、オブジェクト指向設計の原則として、「SOLID」という言葉がある。
それぞれ次の5つの原則の頭文字である。
- Single Responsibility Principle 単一責任の原則
- Open/Closed Principle 開放・閉鎖の原則
- Leskov Substitution Principle リスコフの置換原則
- Interface Segregation Principle インターフェイス分離の原則
- Dependency Inversion Principle 依存関係逆転の原則
こうしたプログラミングにおける原則というものはCSSにそっくりそのまま当てはめることは難しいところもある。
ここでは、比較的取り入れやすいであろう「単一責任の原則」と「開放・閉鎖の原則」について、解説する。
単一責任の原則
言葉の通り、オブジェクトは1つの責任を持つべきであり、その責任は他に影響を与えては行けないというものである。
OOCSSの大前提は、まさにこの原則であり、構造という責任と、見た目という責任を分離して設計することである。
理想的に言えば、テキストのカラーや、サイズやボーダーや背景といった見た目のルールとpositionやfloatなどを一緒のルールセットにしないということである。
それらが分離だれ、それぞれクラスセレクタで適応されることによって、必要に応じて再利用させながらページを作ることができる。
開放・閉鎖の原則
コンポーネントのベースとなるルールというのは、上書き・拡張しやすくあるべき(開放的)で、出来る限り変更をするべきではない(閉鎖的)ということである。
例えば、.btnというボタンコンポーネントのベースとなるルールがあったとして、あるボタンの為に、そのルールが次のように過剰に見た目や構造を持っていたとする。
.btn {
display: inline-block;
border-top: 2px solid #f89;
border-left: 2px solid #f89;
border-right: 2px solid #301;
border-bottom: 2px solid #301;
border-radius: 6px;
………….
}
開発を進めると、必ずこのルールとは異なるボタンがいくつか登場するはずである。その都度、このベースとなるルールを修正するようにしてしまうと、それが他の関連コンポーネントに影響を与えてしまい、ルールが破綻してしまう可能性がある。
そのため、ベースとなるルールというのは、なるべく変更野必要が無いように最小限にし、Modifierで拡張できるようにするほうが利便性が高くなる。
.btn {
display: inline-block;
border-radius: 6px;
text-align: center;
}
.btn--large {
padding: 20px;
font-size: 24px;
}
再利用が全てではない
過剰に再利用することを意識してしまった結果、異なるコンポーネントを混ぜてしまうこともあるかもしれない。
ビジュアルデザイン上、見出しのデザインと、ボタンのデザインが一緒のような見た目であったとする。(UIとして、そもそもいまいちだと思うが。)
<a href=“” class=“btn”>ボタン</a>
<h2 class=“btn heading”>見出し</h2>
同じ要素を再利用するという意味では、正しいかもしれませんが、この実装は好ましくない。ボタンはあくまでもボタンというコンポーネントであり、見出しは見出しというコンポーネントであるべきで、装飾のために他のコンポーネントを混ぜてしまうのは設計として破綻している。これは「単一責任の原則」に従ったアプローチでもある。