CSS設計とは
簡単にいえば破綻しにくいCSSを書こうという問題。
大雑把にいうと共通部分は同じクラスにして使いまわそう、共通化しようというやつです。
今回はCSSを書く前の話(カンプを見るところ)からどういう風にCSSを書くかについて少し書きます。
今回しない話
- OOCSSやBEMやSMACSSについて(moduleごとにCSSファイルわけたりとかそういう話含む)
- 詳しい命名の仕方について
- ファイル管理(ディレクトリ構成)の方法について
- 細かいCSSの書き方について
こんな方向け
- 毎回CSSが破綻する人
- CSS設計するための◯◯の方法とか読んでもいまいちDRY(Dont Repeat Yourself)に書けないという悩みを持っている人
大事なのはいきなりCSSを書かないこと
さてあなたはHTMLとCSSを書くコーダーさんだったりフロントエンドエンジニアさんだったり、あるいはフルスタックエンジニアさんだったりするかもしれません。
ここで多いのが、PSDやpngのカンプを見てざっくりコンテンツの大枠は共通だからこのCSSだなあ、とかざっくりと考えて(設計してるつもり)そのまま実装してしまうこと。
**もっとちゃんと見ないとだめです。**そういう風に考えて大雑把に考えたCSSは間違いなく破綻します。デザイナーさんから、「この見た目のボックス追加して。」と言われてちょっと違うコンポーネントが出てきた時に、なんかCSSうまく共通化できないとなあと思ったことはないでしょうか。そしてまあいっかあで とりあえず書いてしまってはいなかったでしょうか。
CSSはなんとなくでなんとかなってしまうからこそ、そういう思考だと危ないです。ほとんど更新が発生しないWebサイトならともかく常に変化していくWebサービスだと間違いなくCSSが肥大化します。
じゃあ何からやればいいんだよ。
前提条件として、共通テンプレートのPSD1枚、詳細のページ(カテゴリA,B,Cで各3枚あるとします)が9枚の計10枚ほどあがってきてるとします。
やり方は大きく分けて2ステップです。
1. PSDやAIをくまなく見て共通部分を洗い出しましょう。
10枚のPSDを見ながら、共通部分を1つ1つ洗い出しましょう。この時、手書きで紙か何かにざっくりとしたコンポーネントをメモっておきましょう。注意点としては、 **ちょっとだけレイアウト違うんだよな、、だからどうせこれはほぼ同じで共通化!**などと考えず、まず全部洗い出してみましょう。似たようなもので関連がありそうだなと思ったら近くに書いておきましょう。
2. 洗いだした共通部分をもとに、CSSのさまざまなパターンを考えましょう。
共通部分がたくさんでてきたとおもいます。あとはこれを1で書いておいた関連性の近いものをまとめたものの中から、一番シンプルなコンポーネントから実装することを考えていきます。
たとえば、タイトル。見出し1、見出し2、見出し3とフォントサイズは違うかもしれませんが、 色は同じだったりしませんか? こういう時は共通化しましょう。CSSでいうと
.base-title {
color: #555;
}
としておく感じですね。僕の場合は見出し1、見出し2、見出し3と同じものが3個続いたらこれは 共通化しても破綻しにくいだろうと考えます。見出し1と見出し2と見出し3それぞれで色が変わるかもしれないから別々のCSSに書いておいたほうがいいんじゃね?と思うかもしれません。ですが、そこはデザイナーとすり合わせるなりして破綻するリスクを極限まで減らすことを考えたほうがいいです。
なので、
.base-title {
color: #555;
}
.base-sub-title {
@extend .base-title;
color: #333;
}
や
.base-title.base-sub-title {
color: #333;
}
みたいなことをやってはいけません。(当たり前と思うかもしれませんが・・・・)
さて、タイトルで他に考えられるパターンとしたら、例えばタイトルの下に簡単な説明のテキストが入るとかでしょうか。
その時に考えなければいけないことは、
<h2 class="base-title">title</h2>
<h2 class="base-title">title</h2>
<p class="base-description">description</p>
上の2つの場合において
- .base-descritpionを入れてもmargin-bottomの間隔がおかしくならない
- .base-description単体で使った時も汎用的に使えるようになってるk(テキストのコンポーネントとかんがえられる)
の場合を考えなければいけません。
例えば、
.base-title {
margin-bottom: 20px;
}
と書いてるけどそれだと②のときは .base-descritpionの上に20pxも余白が空いてしまってやりたいことじゃなくなってしまう可能性が高くなりますね。デザイン的にいうと.base-descriptionは.base-titleを説明してるものなのに、20pxも離れていたら関連が薄いように見えてしまいます。
さて、これを解決するにはどうしたらいいでしょう。
おすすめは、divで囲ってしまうことです。
<div class="base-title-block">
<h2 class="base-title">title</h2>
</div>
<div class="base-title-block">
<h2 class="base-title">title2</h2>
<p class="base-description">description</p>
</div>
.base-title-block {
margin-bottom: 20px;
}
とでもすればおそらくやりたいことが実現できそうです。
.base-titleや.base-descriptionではフォントや色の指定だけしてればいいですね。
このように、親ボックスはmarginやpaddingやborderなどのレイアウトを指定するだけにして、子要素ではスタイリングをしてあげるとうまくいきます。
なおダメな例は、
.base-title {
margin-bottom: 0;
}
.base-title + .base-description {
margin-bottom: 20px;
}
のように隣の要素だから〜みたいな指定の方法をすることです。.base-titleの下に.base-description以外が来ると破綻しますし、詳細度も無意味に上がってしまいます。
基本的にクラスを別々につけていくことを考えましょう。
ちなみに、タイトルと説明文の色で共通部分があったとしたら
.base-title-block {
color: #333;
margin-bottom: 20px;
}
と色を親要素で追加してしまうのもいいと思います。無駄に.base-titleや.base-descriptionで色を指定する必要がなくなります。
という感じに行っていきます。これを大きいコンポーネントからパターンを考えていって、それが終わったらカテゴリごとに考えていくというのを繰り返していきます。
こうやって設計していくと、divがやたら増えて見にくいんじゃないかと思う人もいるかもしれませんが、細かい変更に耐えるにはそこは仕方ない箇所かなと思って僕は割り切っています。
チームで行う場合は、CSSを書く前に上長に一度確認してもらうのがはじめのうちはいいかもしれませんね。
番外:カンプが全て揃っていないのに実装を始める時
そんな理想通りに実装できないでしょ!そもそもカンプがあがってくるまえに作業するなんてしょっちゅうだわ!と思っている方もいると思います。
そういうときはワイヤーを見てこのへんは共通なんですかね〜?みたいにざっくりでもデザイナーさんに聞いておくのが大事です。デザイナーさんも大枠のイメージは持っているはずなので、リスクを最小限にするためにも聞いておくのがいいです。
また直近で新規のページが追加されるときは、どのページと同じようなレイアウトになるかも聞いておくと命名の時に悩むことが少なくなるかもしれません。
以上簡単ですが僕が実際に行っているCSS設計のプロセスのまとめでした。