拡張性、再利用性、可読性の高いコードパターン - CSS編

快適なコーディングを楽しむための新しいコードパターン（とファイルパターン）を提示します。

*2014-08-09追記：*
*長くなったのでHTML(PHP)編,CSS編,JavaScript編に分けました。*
*過去の投稿からご参照頂ければと思います*

Webコーディングでもっとも対処すべき課題は**範囲（スコープ）を明示し独立させる**ことです。
（HTMLやCSSはスコープがないために読みづらく冗長だと考えます）

HTMLは構造、CSSはプレゼンテーション、JavaScriptは振る舞いというそれぞれの役割の意味をしっかり吟味し根本から再考しています。

##CSS

####HTMLのclassにスタイルの情報を与えるべきか？
HTMLにスタイルの情報をもたせないという本来のHTMLの役割を全うしたかったのですが、そうはいきませんでした。
もし本来のHTML用途にそってその要素が何かという情報だけで組んだ場合（つまり、class="red"やclass="skin1"を与えない場合）、CSSはひとつのスタイルに対し、**セレクター**の数が増えてしまいます。▼

```css:例
#parentA .child1 .button,
#parentB .child1 .button,
#parentC .child1 .button,
#parentD .child1 .button{
  /* ボタンのスタイルA */
}
#parentA .child2 .button,
#parentB .child2 .button,
#parentC .child2 .button,
#parentD .child2 .button{
  /* ボタンのスタイルB */
}
```
一見セレクタが増えることはあるべき姿なのかと思えます。
しかし例えば、**抽象的なボタンのスタイルから拡張したい場合**はこれができません。
そのため以下のようにスタイルの情報をHTMLのclassに含める必要があるのです。

```html:解決
<div class="button button_skin1"></div>

```

```css:解決
.button{
  /* 抽象的なボタンのスタイル */
}
.button.button_skin1{
  /* .buttonの拡張スタイル */
}
.button.button_skin2{
  /* .buttonの拡張スタイル */
}
```

###入れ子要素に被らないようにするにはユニークな組み合わせが必要
CSSで最も予期しない出来事は、子要素にかけたスタイルが孫要素に反映されていることです。特にtableもしくはulをさらに入れ子にした場合に起こり得ます。

第一階層のtableのtdのみに反映したい場合、通常ではこのように書かなければなりません。

```css
#hoge > table > tbody > tr > td{
  ...
}

/* これは第二階層も反映されてしまいます */
#hoge > table td{}
#hoge table tbody tr > td{} 
```
子セレクタ'>'を使うことは推奨しません。JavaScriptなどで予期せぬwrapper要素が間に入るとも限らないからです（もし入るとスタイルが失われてしまいます）。

次のようにするとHTMLのclassが少し冗長になりますが、やりたかったことがきれいに実現できます。

```html:解決
<!-- 便宜上trやtableにもclassを与えていますが、スタイルを当てる必要がなければ省略してOKです -->
<table class="shops">
  <tr class="shops">
     <td class="shops">
       <table class="items">...</table>
...
```

```css:解決
/* ↓注目 */
#hoge td.shops{
  ...
}
/* #hogeも省略して良い */
```

さらにマルチクラスを用いるなどしてユニークな組み合わせを積極的に使っていくことで、cssやjQueryのセレクタがすっきりしていき、DOM探査速度の向上だけでなく、人間の可読性にも一役買うことができます。

###gadgetごとにid
**gadget※に対しidをふっておく**ことで、cssやjQueryのセレクタがすっきりし、DOM探査速度も向上します。▼

※HTML(PHP)編参照

```css:例
#chooseProductForm {...}
#chooseProductForm .product{...}
#chooseProductForm .thumbnail{...}
```
```js:例
var $photoSlideshow = $('#photoSlideshow');

var $flip    = $photoSlideshow.find('.flip');
var $photo   = $photoSlideshow.find('.photo');
var $caption = $photoSlideshow.find('.caption');

...
```

###ファイルパターン
スタイルを分離したいならこのようにします。
1. layout.css
2. gadget.css
3. tuning.css

layout.cssとgadget.cssの役割はお考えの通りだと思います。※
この２つはHTMLの分離のしかたに対応しています。また、gadget.cssはgadgetの数だけ記述が多くなりますが、gadgetの頭にidをつけているのでどれだけ記述が増えようと探しにくいことはありません。▼

※HTML(PHP)編参照

```css:gadget.css
...
#chooseProductForm .caption {...}
#chooseProductForm .caption span {...}

/*----------------------------------------*/
/* #photoSlideshow
/*----------------------------------------*/
#photoSlideshow {...}
#photoSlideshow .relativeFrame {...}
...
```

**tuning.css**
h2やpなどでよくみられる**イレギュラーなマージンの定義**は、
初期値だけgadget.cssに定義し、イレギュラー値をtuning.cssに定義することで解消できます。

**プレフィックス**
topページやformページなどでみられる**ページ特有のスタイル**を他の（大多数の）記事ページと切り離したい場合は、プレフィックスを用いて明示します。
4. toppage_gadget.css
5. toppage_tuning.css
6. form_gadget.css
7. form_tuning.css

これで管理がすこぶる捗るはずです。


##おわりに

さらに快適なコードパターン実現のために、あなたのコードパターンやファイルパターンを教えて下さい。また、私の解説上で難解な部分、指摘箇所なども伝えていただけると大変幸いです。

他HTML(PHP)編,JavaScript編もご参照ください。