2010-02-08
OOCSS(Object-Oriented CSS)の考え方
CSSでサイトを作るとき、ページをidで区切り、その中のclassに対してスタイルを指定するというやり方が一般的じゃないかなと思います。
#page-foo .box {margin:10px }
#page-baa .box {margin:20px }
しかし、いざあのページのこの部分をこのページに持ってきたい…となるとCSSファイルごと持ってこなければならない、移転先のclass名とバッティングしてしまうなど再利用が難しいという反面もあります。
今回仕事でサイトを構築するにあたり、再利用可能なモジュールで構成すればコーディングにかかる工数は減るのではと考えていたので(特にIEのバグ関連…検証済みのモジュールで構成すれば確実!)再利用性とパフォーマンスを重視したフレームワークOOCSSについて調べてみました。
OOCSSの基本的な考え方
目的別にclassを複数指定する。
idに依存するロケーションで見た目を区切るのではなく、使われ方に応じてclass名をつけます。ソースで説明してもわかりにくいので例をあげます。ここでは「ダイニングテーブルに置かれたリボンのついた大きな箱」をマークアップするとします。
ロケーション別に分ける場合
<div id="#ダイニングテーブル"> <div class="リボンのついた大きな箱">…</div> </div>
とマークアップしていました。
しかしOOCSSでは
<div> <div class="箱 大きい リボン">…</div> </div>
と記述しています。ダイニングテーブルかち無視です。しかし、この箱はちゃぶ台の上にもそのまま置けるようになったわけですw
また、「シールの貼ってある小さな箱」を表現したいときも
<div> <div class="箱 小さい シール">…</div> </div>
となり、「.箱」は再利用できるわけです。
無駄に箱のスタイルをいくつも記述する必要がなくなりますね。同じように「大きい、小さい」も「箱」だけでなく「袋」なんかにも再利用できるわけです。良く考えてみれば箱の例のように、箱という機能はテーブルによって左右されるわけじゃないですもんね。どこにあっても箱は箱として使える!これ箱としての大前提!ってことですね。
構造とスキンを分離する
先程の例で言うと「箱」「大きい」が構造、「リボン」がスキンになります。実際にOOCSSのテンプレートを見てみると、以下の図のようになっています。
「.line」がページに横たわっている大枠、「.unit」「.size1of3」がカラムとその幅、「.mod」がモジュールといった構造を表わしています。「.grab」「.excerpt」「.sommers」はモジュールに当てられたスキンです。構造には marginやfloatなどの隣接要素に影響を与えるプロパティが、スキンにはbackground、borderなどの装飾系プロパティがシンプルに指定されています。
パフォーマンスが良い
ロケーションでぐちゃぐちゃ書かない分、CSS記述がシンプルになりパフォーマンスが良くなります。子孫セレクタはパフォーマンスに良くありません。(そんなに変わらんとの説ありですが…)
【before】
#page-hoge .hogebox . hogeclass {・・・}
【after】
.hogeclass {・・・}
実際に使ってみて
CSSでここまで構造について真剣に考えたことは、恥ずかしながらありませんでしたw
いままではある程度場当たり的に「ここはこのくらいのmarginでいいだろー」で済んでいた部分が、「ここは.lineだからmarginはいくつで…」とかっちり決めて置かないとすべてに影響してしまうのです。後々の再利用のことまで考えてコーディングしないといけないので、初期工数はかかりますが、再利用性は申し分ないです。
自分は、スキンのライブラリページをまずコーディングし、そこからコピペでパズルのようにページにはめこんでいく方法をとっています。検証済みの構造の上にスキンをかぶせていくだけなのでブラウザ間の表示崩れもありません。
ぶっちゃけテンプレートのhtmlはパフォーマンスや汎用性を持たせるためか、ちょっと複雑な作りになっています。実際に使用するには厳しい部分も結構あると思います。(角丸のために空のbタグが大量にあったり…)なので、テンプレートを直接カスタマイズするよりは考え方を身につけて要件に合わせ自分で構築していった方がいいかもしれません。
どれだけ優れたフレームワークもあくまで道具でしかなく、自分の手になじませないといいものは作れないと思いました。
- 1 http://b.hatena.ne.jp/icgm/ISHIKAWA/
- 1 http://d.hatena.ne.jp/diarylist?of=150&mode=rss&type=public
- 1 http://d.hatena.ne.jp/h1mesuke/edit?date=20100209
- 1 http://d.hatena.ne.jp/icgm/
- 1 http://d.hatena.ne.jp/in0in0
- 1 http://d.hatena.ne.jp/ytakano/20100211/1265908567
- 1 http://ig.gmodules.com/gadgets/ifr?view=home&url=http://gadgets.bashennekam.nl/twitter/gadget.xml&nocache=0&up_feed=friends&up_username=taki666&up_items=5&up_refresh=600000&up_last=&lang=ja&country=jp&.lang=ja&.country=jp&synd=ig&mid=127&ifpctok=145628553
- 1 http://twitter.com/
- 1 http://twitter.com/in0in0
- 1 http://twitter.com/search?q=#dtt03

