CSSは記述の自由度が高い(制約が少ない)ため、ルールやプロットを設けずになんとなくコーディングしていると、非常に複雑で、理解しにくいものとなってしまいます。
そのセレクタはいったい何を意図して作られたのか
同じセレクタが複数存在し、互いにバッティングし合っている
どこで使われているセレクタなのかわからない
などといった問題が発生します。
このようなCSSは修正も容易ではありません。
内部構造が複雑になっているので、ある変更が別の個所に影響を及ぼす可能性があるからです。
そうならないためには、保守性、再利用性の高いCSSの記述を心がけないといけません。
目次
保守性、再利用性の高いCSS
では、保守性、再利用性に優れたCSSを記述するにはどうしたらいいでしょうか。
そのためには、以下のような原則を守るべきです。
・完璧な設計を求めるのではなく、修正がしやすい設計をする
・1年後の自分が読んで理解できるコードか
・常に修正されることを意識してコーディングする
これはCSSだけでなく、プログラム全般に言えることです。
また、以下のようなことも意識するといいでしょう。
・予測しやすい…ルールどうしがバッティングしない、干渉しあわないこと
・再利用しやすい…個別化しない、抽象化する、機能ごとに分類する
・保守しやすい…追加したルールによって既存のルールを破壊しないこと
・理解しやすい…学習コストが低い
破綻しやすいCSS
では、今度は逆によくないCSSを考えてみましょう。
破綻しやすい、望ましくないCSSは以下のような特徴を持っています。
HTMLの構造に依存している
例)
article要素のh1要素に対して、セレクタを指定。
しかし、HTMLの構造が「div > h2」になった時、CSSも修正する必要がある。
その場合、要素名でなく、classをセレクタに使用していれば、CSSの修正は不要になる。
つまり、HTMLに変更が生じてもCSSを変更しなくても済むような構造にすることが重要。
ルールを取り消している
取り消しルールを追加すると、無駄なコードが増えます。
例)
アンダーラインの装飾を取り消す場合、アンダーラインを引くための指定と、アンダーラインの設定を取り消す行が必要になる。
一方、取り消すのでなく、追加するような運用にすると、アンダーラインを引くための設定だけでよくなる。
×悪い例
1 2 3 4 5 6 7 8 |
.title { border-bottom:2px solid #000; //アンダーラインを引く設定 font-size:24px; } .no-border { border-bottom: none; //アンダーラインを打ち消す設定 } |
○いい例
1 2 3 4 5 6 7 |
.title { font-size:24px; } .add-border { border-bottom:2px solid #000; } |
ルールは取り消すのではなく、追加するようにすると重複が少なくて済みます。
絶対値を使用しない
例)
フォントサイズと行間を絶対値で指定している場合、フォントサイズ変更時に、行間の値も飼えないといけない。
しかし、行間を相対値で設定しておけば、フォントサイズの変更に連動して、行間も変わる。
つまり、修正がフォントサイズのみで済む。
セレクタの詳細度が高い
例)
h2 .title(h2要素、かつclass=”title”)のようなセレクタが存在している。
しかし、h2以外にもtitleクラスを適用することは今後ありうるし、他の要素でも使えるようにしておくべき。
ちなみに、セレクタの詳細度の高さは以下のようになります。(左の指定から優先されていきます)
!important < インライン記述(style属性) < idセレクタ < クラス、属性セレクタ < 要素セレクタ < ユニバーサルセレクタ(*)
・子孫セレクタについて
li要素以下のすべてのa要素に適用
ul a
ul要素配下のli要素配下のa要素のみに適用(限定的)
ul > li > a
======================================
ここで紹介している例は、ほんの些細なものです。
しかし、このような小さなことの積み重ねが、修正しにくい複雑なコードを生み出すのです。
逆に言えば、このような些細なことを意識すれば、修正しやすい、シンプルなコードを書くことができるのです。
CSSのコンポーネント化
コンポーネント化というのは、部品化という意味です。
部品化することで、修正や変更を容易にすることができます。
・修正による影響が部品内で完結する。他に影響を与えない。
・配置をすぐに変更できる。(右カラムにあったものを左に移動させる)
CSSのコンポーネント化のフレームワークとしては、OOCSS(Object Oriented CSS)やSMACSSがあります。
大事なのは、機能ごとに分離することです。
そのために、SMACSSでは、機能ごとに以下のようなカテゴライズを行うことを推奨しています。
・Base…各要素のデフォルトスタイル。フォントサイズや、背景色など。
・Layout…セクションやコンテナー。(headerとかdivなど)
・Module…構成要素全て。ボタンやリンク、テキストボックスなど。
・State…JavaScriptなどによる制御によって切り替わるような状態を表すルール。is-tab-activeやis-hiddenなど。
・Theme…テーマによって変わるもの。背景色やフォントなど。
上記のような分類を行うならば、接頭辞をつけることで、どの機能なのかがわかりやすくなります。
たとえば、その要素がLayoutの機能を有するならば、「l-gridItem」のように接頭辞をつけるとわかりやすくなる
コンポーネント化の落とし穴
コンポーネント化の考え方は大事ですが、最初からそれにこだわるのはあまり望ましくありません。
再利用性を考えて時間をかけて作ったものが、その後二度と再利用されない可能性もあるからです。
CSSに限った話ではないですが、再利用性は、そのパターンが3回以上繰り返された時、はじめて考えるのがいいでしょう。
CSSの命名規則
命名規則に求められるものは、
・わかりやすさ
・バッティングしないこと
です。
わかりやすさ
わかりやすさを追求するためには、統一性が重要です。
たとえば、CSSのセレクタを以下の3要素に分けます。
・コンテナー…メッセージエリア
・コンテンツ…メッセージ
・修飾…エラー、ワーニング、インフォメーションなど
これらの要素の関係は以下のようになります。
・コンテナーはコンテンツを内包する
・修飾はコンテンツとセットで使われる
そのため、以下のような命名規則にすると、何の要素なのかと使用箇所が明確になります。
・コンテナーはコンテンツを内包する….container_contets
・修飾はコンテンツとセットで使われる….container_contents-modify
「_」が内包関係を表し、「-」が修飾を表します。
また、接頭辞をつけて一目で機能の分類がわかるようにするのも有効でしょう。
バッティングしないこと
ここで言うバッティングとは、名称がカブることを言っています。
たとえば、warningのような抽象的な名称だと、カブる可能性が高くなります。
メッセージエリアでのワーニングメッセージとページのコンテンツ内の注意情報とでバッティングするなどです。
CSSでは、スコープが決まっていないため、ルールを作って使用箇所を限定してやる必要があります。
たとえば、上位コンポーネント名を名前空間とすることで、使用箇所を限定するなどです。
こうしたことをすることで、どこで使われているかわからない、それによって意図しない干渉が起こる可能性を押さえることができます。
![]() |