what is OOCSS

object-oriented CSSについてのさわり。

いろいろなサイトを読んだ結果、OOCSSとは簡単に言うと

オブジェクト指向設計に基づいたCSSで保守性と拡張性を得よう!

ということだと解釈した。

そのための簡単な手法として例を挙げると

  • なるべく子孫セレクタなどを使うのはやめて、クラス指定で書きましょう。
  • クラス指定も最小限のクラスを複数書くことで、cssに同じ事を何度も書かなくて良いようにしましょう。

ということだ。

具体例として

    .foo .bar + .bar { ~~~~}
    div:nth-child(n) {~~~~}
    el > el:first-child {~~~~}

上記のようにセレクタを記述すると書いた本人は良いが、他の人には伝わらない。
そこで、何を指定しているかがはっきりと分かるように明示的にセレクタを記述しなければいけない。

    ☓ header ul {~~~~}.site-nav {~~~~}

クラス名は、そのクラスが行う役割などを考えながらreasonableに命名する。
内容などを書いてしまっては、拡張性が失われてしまうのでやめておいたほうが良い。


では以下で、具体的にOOCSSについて書いていく。





Whta is CSS Object?

OOCSSには2つの大原則がある。

structure とskin とを独立させる。

  • structure: margin , topなど、要素の場所などに関係すること
  • skin: background , borderなど、要素の見た目に関すること

この2つを独立させることにより、最小限のコードでより多くの整備されたHTMLを得ることができる。

HTMLのセマンティックさ頼るよりも,structure, skinにオブジェクトやコンポーネントの名前をclassとして使ったほうが良い。
例えばmedia ojectの場合

<media class="media">

とする、その中のコンポーネントであるimgにはわざわざ

<img class="img">

をつける。
body やtext component なら

<body class="bd">

という風にする。

理由としては、img element ではなくimg クラスを参照することで、
もしここ数年で、elementが変化してしまった場合でも、cssに手を加えることなくhtmlを変更することができるからである。

content とcontainerを独立させる。

本質的には、
ほとんど位置に依存したスタイリングはしない。
ように記述する。

例えば,h2なら、

.myobject h2 {~~~~~}

というような記述はせずに

<h2 class="category">

というようにHTML側でクラス属性をつけてあげる。

理由は

.myobject h2 {~~~~~}

となっている場合、.myobjectの中のh2をスタイルし直す時に、cssセレクタの深さを考えて高いレベルでのスタイル指定が必要になってしまうからだ。




セマンティックに書こう

わざわざコンテンツに関連させたようなクラス名は要らない

html5になってからタグや属性にある程度の意味を付けられるようになった。
そのため、クラス名がコンテンツをそのまま反映するのではなく、コンテンツ同士の関係を明確に表すようなクラス名をつけるのが良いだろう。

クラスの具体的な付け方

単一クラスパターン

    .btn, .btn-primary { /* button template styles */ }
    .btn-primary { /* styles specific to save button */ }

    <button class="btn">Default</button>
    <button class="btn-primary">Login</button>

マルチクラスパターン

    .btn { /* button template styles */ }
    .btn-primary { /* styles specific to primary button */ }

    <button class="btn">Default</button>
    <button class="btn btn-primary">Login</button>

この2つを見比べると
単一クラスパターンは.btm-primaryの中に.btmが含まれている(類似している)。
一方、マルチクラスパターンは.btmと.btm-primaryが独立している(全くの別物と考えることができる)。
そのため、拡張性という面から見ると、マルチクラスパターンを利用したほうが使用するトータルクラス数では圧倒的に少ないので、マルチクラスパターンを使用したほうが良いだろう。






OOCSSを使用するメリット

ここまでOOCSSを推してきたわけだが、ここで一度、OOCSSを使用した時のメリットについて見なおしてみる。

メリット

  1. cssがより簡単になる
  2. 変更を加えたい時、1箇所を変更しただけで全体のデザインを変えることができる。+
  3. 変更を加えるとき、1クラス1機能なので、安全に変更を加えることができる。
  4. 多くのクラスで定義されている機能を組み合わせることができる。


OOCSSを考えずにコーディングをすると以下のようになる。

<div id=header>
</div>

<div id=content>
</div>

<div id=sub-content>
</div>

<div id=footer>
</div>

#header{
    padding:20px;
    margin-bottom:20px;
    background-color:#121416;
    color:#fff;
}

#content{
    width:640px;
    float:left;
    margin-right:20px;
    padding:20px;
    margin-bottom:20px;
}

#sub-content{
    width:280px;
    float:left;
    padding:20px;
    margin-bottom:20px;
}

#footer{
    padding:20px;
    margin-bottom:20px;
    background-color:#e4e4e4;
    color:#333;
}


ここでOOCSSを意識しながらコーディングすると

<div class="island header">
</div>

<div class="island content">

    <h2>Buy now with promo code <span class=promo>0MG4WE50ME</span></h2>

</div>

<div class="island sub-content">

    <a href=product class="island promo">Buy now!</a>

</div>

<div class="island footer">
</div>

.island{
    display:block;
    padding:20px;
    margin-bottom:20px;
}

.promo{
    background-color:#09f;
    color:#fff;
    tex-shadow:0 0 1px rgba(0,0,0,0.25);
    border-radius:4px;
}

.header{
    background-color:#121416;
    color:#fff;
}

.content{
    width:640px;
    float:left;
    margin-right:20px;
}

.sub-content{
    width:280px;
    float:left;
}

.footer{
    background-color:#e4e4e4;
    color:#333;
}


上記のようになる。
OOCSSを意識していない方は、コンテンツを増やそうとすると、そのdiv要素にidをつけて、そのid専用のcssを書いてあげないといけない。
しかし、一方OOCSSを意識しながらコーディングした方は、新しいコンテンツに適しているクラスを幾つか選び、つけてあげるだけで拡張することができる。




OOCSS+Sass

プレーンなcssでモジュールを作るための唯一の方法は非セマンティックにクラスを定義することだ。
しかし、それには2つの問題が生じる。

  1. スタイルを変更するときに毎回htmlを変更したくない。(スタイルは常に変更されるものであるにも関わらず)
  2. クラスを追加したいDOM要素にアクセス出来ない。もし、ページ内にjsのコンポーネントを使用していても、変な記述をしない限り、その要素内にクラスを追加することはできない。

プレーンなモジュールを繰り返し使い抽象化することが、大規模なプロジェクトで保守性を維持する唯一の方法である。では、上記のような欠点なしに、メリットを得るにはどうすると良いか。

OOSass

OOCSSとSassを組み合わせるのが正解。
@extendと@mixinを使うことで、同じような記述を何度も繰り返さなくても、別のセレクタでもクラスを継承することができる。
しかし、コードを入れ子にすることで、コード量が増えてしまう。

しかし、sass3.2でプレースホルダーという機能が追加されたことによって、この問題は解決された。
以下に例を示す。

Sass

%separator
    border-top: 1px solid black

hr
    @extend %separator

.separator
    @extend %separator


css

hr,
.separator {
    border-top: 1px solid black
}

こういった機能によってコードの肥大化が防がれる。

実際に使われそうなケース

仮に.mediaというモジュールを、.status .profileなどに継承したいとする。
これまでだったら、.status .profileなどにも.mediaに書いたものと同じ記述をしなければいけなかったが、
sassをつかうと

%media
    overflow: hidden
    &:first-child
        float: left
    &:last-child
        overflow: hidden


.status
    @extend %media
    // Status-specific styles here...

.profile
    @extend %media
    // Profile-specific styles here...

と、記述することができる。

これによって、記述量もなり.status .profileもセマンティックなクラスになったといえる。


最後に

OOCSSとはセマンティックに、わかりやすく書くためのものである。
そのため、クラスの命名規則が重要になる。
自分が考えだしたクラス名より、ある程度すでに使われているクラス名のほうが
自分以外がコードを見た時に理解しやすいということで、以下のサイトを参考にすると良さげだった。

http://css-happylife.com/archives/2007/0115_1345.php






参考サイト
http://csswizardry.com/2012/10/a-classless-class-on-using-more-classes-in-your-html/
http://ianstormtaylor.com/oocss-plus-sass-is-the-best-way-to-css/
http://enja.studiomohawk.com/2012/03/20/about-html-semantics-and-front-end-architecture/
https://github.com/stubbornella/oocss/wiki