CSS設計についての再考
OOCSS(オブジェクト指向CSS)を再考する
※OOCSSについては過去記事を参照のこと
OOCSS(オブジェクト指向CSS)のススメ
難しいOOCSS(オブジェクト指向CSS)の設計
再利用性の範囲を2つに分けて考える
OOCSSはとにかくクラスを細分化すればいいってもんではない。
クラス=プロパティ レベルまで細分化されたCSSは、煩雑になるばかりかコストも高くなる。
だが、細分化すること自体が悪いわけではない。
失敗に陥るのは、再利用性の範囲を明確にしていないため。
再利用可能な範囲とは?
いま製作しているサイト内?
それともあらゆるサイト?
まずはこの線引きをしっかりすることが重要だと思う。
プロセッサー型CSSフレームワークmaple.cssのヘルパーには以下のようなクラスが定義されている。(抜粋
.ref { position: relative; }
.abs { position: absolute; }
.fl { float: left; }
.fr { float: right; }
.dn { display: none !important; }
.db { display: block !important; }
.di { display: inline !important; }
.ds { display: inline-block !important; }
.dt { display: table !important; }
.dc { display: table-cell !important;}
.mtn { margin-top: 0 !important; }
.mts { margin-top: $space-base !important; }
.mtm { margin-top: $space-2 !important; }
.mtl { margin-top: $space-3 !important; }
.mtx { margin-top: $space-4 !important; }
クラス=プロパティ レベルまで細分化されてるクラス定義ではあるものの、再利用性の範囲が明確になっている。
再利用性の範囲は、あらゆるサイト。
このクラス郡をスーパー汎用クラスと呼ぶことにする。
となると、OOCSSによる構造とスキンの分離によって定義される汎用クラスの再利用性の範囲は、いま製作しているサイト、となる。
このクラス郡を汎用クラスと呼ぶことにする。
汎用クラス: 再利用性の範囲 = いま製作しているサイト
サンプルコード1
スーパー汎用クラスと汎用クラスがうまく設計されている例
<div class="line"> <div class="unit half"> <div class="mod mod-basic"> <div class="p20"> <ul> <li><p class="c">123</p></li> <li><p class="c">333</p></li> <li><p class="c">222</p></li> </ul> </div> </div> </div> </div>
/* スーパー汎用クラス */
.p20 { padding: 20px; }
.c { text-align: center !important; }
.half { width: 50% !important; }
/* 汎用クラス OOCSS 構造 */
.line {
overflow: hidden;
zoom: 1;
}
.unit {
float: left;
width: 100%;
}
.mod {
margin: 5px;
border-radius: 10px;
-webkit-border-radius: 10px;
}
/* 汎用クラス OOCSS スキン */
.mod-basic {
box-shadow:rgba(200, 200, 200, 0.631373) 0px 0px 20px 3px inset;
-webkit-box-shadow:rgba(200, 200, 200, 0.631373) 0px 0px 20px 3px inset;
background-color: rgba(255,255,255,0.15);
}
CSSとマークアップでコストを分散させるというプロセスを経て
OOCSSの考え方では、構造とスキンに分離された汎用クラスを定義して、それをマークアップ側で複数組み合わせて使うことになる。
ある意味、マークアップ側がコスト高になる。
いくらクラスを複数組み合わせると言っても、やはり無駄は排除したい。
例えば以下のようなスタイルを定義する場合

サンプルコード2
とにかくOOCSSっぽくクラス定義して失敗する例
<div class="ref bg-skin-1 w200 h200"> <span class="label abs label-structure-1 label-skin-1">hoge</span> </div>
/* スーパー汎用クラス */
.ref { position: relative; }
.abs { position: absolute; }
/* 汎用クラス OOCSS 構造? */
.w200 { width: 200px; }
.h200 { height: 200px; }
.label {
display: inline-block;
font-size: 16px;
padding: 4px 8px;
border-radius: 20px;
color: #FFF;
background-color: #CCC;
}
.label-structure-1 {
top: 20px;
left: 20px;
}
/* 汎用クラス OOCSS スキン? */
.bg-skin-1 { background-color: #EEE; }
.label-skin-1 {
background-color: blue;
}
クラス名もあえて変な名前で付けてみましたが、とにかく無理矢理感。
というよりも、ここで定義されている汎用クラスに再利用性はほぼないと言えるでしょう。
再利用性がゼロでは汎用クラスの意味はないので、OOCSSっぽく設計しても無駄ということになります。
すべてのスタイルをスーパー汎用クラスと汎用クラスで定義することは、まず不可能。
うまく設計したとしても、やはり溢れるスタイル、再利用性のない固有のスタイルというのは存在するものです。
固有のスタイルは固有のスタイルとして、例えば以下のようにセレクタ指定で定義した方がよっぽどいいと思われます。
サンプルコード3
<div class="hoge"> <span>hoge</span> </div>
/* セレクタ指定型 */
.hoge {
position: relative;
width: 200px;
height: 200px;
background-color: #EEE;
}
.hoge > span {
position: absolute;
top: 20px;
left: 20px;
display: inline-block;
font-size: 16px;
padding: 4px 8px;
border-radius: 20px;
color: #FFF;
background-color: blue;
}
どちらがコストが低いかは一目瞭然。
CSSとマークアップのコスト面にも注目して再認識するのが、固有クラスの存在感。
CSS設計のまとめ
再考から導き出したCSS設計をまとめると、CSSは以下の5つに分類されそう。
2. スーパー汎用クラス
3. 汎用クラス(OOCSS構造)
4. 汎用クラス(OOCSSスキン)
5. 固有クラス
1. リセットCSS
ブラウザ依存のスタイルをリセットするCSS
2. スーパー汎用クラス(OOCSS)
あらゆるサイトで再利用性可能な細分化された汎用クラス
3. 汎用クラス(OOCSS構造)
いま製作しているサイトで再利用可能な汎用クラス
OOCSSの構造とスキンの分離における構造の部分
4. 汎用クラス(OOCSSスキン)
いま製作しているサイトで再利用可能な汎用クラス
OOCSSの構造とスキンの分離におけるスキンの部分
5. 固有クラス
再利用性がない固有クラス
セレクタ指定によるマークアップ主導型CSS
CSSはそもそもの仕様が煩雑になりやすい言語なので、完全に煩雑さをなくした設計は不可能に近い。
それでも以上のような手順で設計を行えば、その煩雑さを軽減し、メンテナブルなCSS設計が可能になるのではないかなぁ。