- ブラウザスタイルは平坦化しておく
- リセットCSSはオプトアウト可能にしておく
- 登場頻度の高い組合せはplaceholderとして登録してから利用する
- 可能な限り画像はスプライト生成してから利用する
- それ以上分解不可能なコンポーネントは要素のように扱う
- コンポーネントは自己完結型のものを使う
- BEMはDRYになるよう粒度を下げる
- 可能な限り
@extend
は利用しない - レスポンシブでない場所では、Utilitiesクラスを活用する
- shame.cssはいつも綺麗にしておく
- 詳細度または特異性の高いものほど後方に記述する
- 可能な限り
!important
しない - 可能な限りハックしない
- 変数をデザインガイドとして活用する
- CSSファイルを分割するメリットはほとんどないので一つにまとめる
1. ブラウザスタイルは平坦化しておく
例えば、こういうScrap & Buildは単に通信量のムダ。
* {
font-weight: normal;
vertical-align: baseline;
}
b, strong {
font-weight: bold;
}
sub {
vertical-align: sub;
}
normalize.cssで平坦化した上で、さらに必要と思うリセットを施せばいいだけ。
2. リセットCSSはオプトアウト可能にしておく
例えば、箇条書きのスタイルを普通にリセットしてしまうと、本当に箇条書きとして使いたい時に困る。
ul {
margin: 0;
padding: 0;
list-style: none;
}
以下のようにリセットすれば、オプトインするかオプトアウトするかを都度選択できる。
.ul {
margin: 0;
padding: 0;
list-style: none;
}
<ul class="ul">
<ul>
nondestructive-reset.css(非破壊的リセットCSS)なら、いつものリセットと同じ記述量で、二倍の選択肢が得られる。
3. 登場頻度の高い組合せはplaceholderとして登録してから利用する
二つ以上のプロパティをセットで書くことが多いのであれば、まずはplaceholderとして登録する。
%link--tint
color: blue
text-decoration: none
.some-link
@extend %link--tint
link--tint()
color blue
text-decoration none
.some-link
link--tint()
出力結果はいずれも、
.some-link {
color: #00f;
text-decoration: none;
}
厳密にいうと、Stylusの方はplaceholderを@extend
ではなく@include
しているので、タイプ数も含めてStylusの方が優れている。@extend
については後述。
4. 可能な限り画像はスプライト生成してから利用する
background-repeat
させない画像であれば、原則スプライトにする。@extend
やMixinを経由して呼び出すことで、記述量を最小限にできる。
.foo
@extend .sprite--logo
.foo
sprite("logo.png")
自動生成なら width
・height
・background
プロパティなどを記述不要にできる。画像までのパスも不問で、ファイル名だけが分かればいい。
5. それ以上分解不可能なコンポーネントは要素のように扱う
Web Componentsのようにとは言いませんが、AngularJSのディレクティブやJadeのMixinを利用したカスタムタグなど、内部構造が容易に変更できないHTMLコンポーネントは、select
タグのようなHTML要素を扱うのと同様に扱う。
つまり、内部構造のスタイルを定義していいのは、そのコンポーネント自身だけ。
6. コンポーネントは自己完結型のものを使う
自己完結していないコンポーネントの例として、Bootstrapのnavbarはfixed
レイアウトの際に、他の要素へ依存するのでよくない。
body {
padding-top: 70px;
}
そう書いたのを忘れた頃に<div class="navbar">
を取り除くページがあったりすると、辛い。こういうことが積み重なると、とても辛い。
.navbar__wrapper {
height: 70px;
}
のように、自己完結型に修正してから利用する。
7. BEMはDRYになるよう粒度を下げる
BEMは、class名が長くなるので倦厭されることもありますが、まさにそこがBEMのメリットで、レイアウトのバリエーションが何百になっても「命名の衝突」を簡単に回避できます。(アンダースコア派かハイフン派か、といった宗教戦争を回避できるのもメリット)
ただし、Blockの粒度を適度に分割しないと全然DRYにならずに、記述量が増える一方なので注意が必要です。
例えば、
<ul class="list">
<li class="list__item">
<div class="list__item__header">
とするのもいいけど、
<ul class="list">
<li class="list__item card">
<div class="card__header">
のように、コンポーネント単位で委譲できると素敵。
8. 可能な限り@extend
は利用しない
@extend
と@media
は衝突する概念なので、レスポンシブ・デザイン等では併用が困難。
%link--print
color: black
text-decoration: dotted
.some-link
color: blue
text-decoration: none
@media (print)
@extend %link--print
出力結果は意図しない形に、
.some-link {
color: blue;
text-decoration: none;
}
.some-link {
color: black;
text-decoration: dotted;
}
代わりに@include
を使えば大丈夫。
@mixin link--print
color: black
text-decoration: dotted
.some-link
color: blue
text-decoration: none
@media (print)
+link--print
.some-link {
color: blue;
text-decoration: none;
}
@media (print) {
.some-link {
color: black;
text-decoration: dotted;
}
}
望んだ結果になりました。Stylusでも同様です。
link--print()
color black
text-decoration dotted
.some-link
color blue
text-decoration none
@media (print)
link--print()
9. レスポンシブでない場所では、Utilitiesクラスを活用する
UtilitiesクラスというのはCSS界のワンライナーのことです。
.hidden { display: none !important; }
HTML側に直接記述して利用するので、レスポンシブな部位とは相性が悪い。
<div class="sidebar hidden">
レスポンシブでない部分(状態変化がない部分)であれば、活用することでCSSの量を減らせます。
<h1 class="h1 section__title text--center">
.text--center { text-align: center; }
BEMを押し通すなら以下のようになりますが、厳格すぎるとDRYにならずにコード量が増えます。
<h1 class="section__title section__title--centered">
.section
&__title
&--centered
text-align: center
Utilitiesクラスは、大量に発行すると「命名の危機」を引き起こすので、拡張性を考えて作りましょう。globalize.cssというUtilitiesクラス専用のライブラリもあります。
10. shame.cssはいつも綺麗にしておく
shame.cssとは、綺麗にしておかないと恥ずかしいものを書く場所です。
レイアウト上のバグが見つかった時、一時しのぎなコードを書くのに使います。
.page__footer
overflow: hidden // I don't know why but it fixes our problem.
overflow: hidden
されては困ると、別の誰かが文句を言うかもしれません。
$ git blame _shame.sass
解決したらしかるべき場所に移しましょう。
.page__footer
+clearfix
// Keep this file clean.
11. 詳細度または特異性の高いものほど後方に記述する
書き順については、セレクタの詳細度またはスタイルの特異性を考慮しながら決める。
- 詳細度の高いセレクタを上書きするためには、さらに高い詳細度が必要になり、それを上書きするために...となるので、まずは詳細度の高いセレクタを作らないこと。どうしても必要な場合は後方に書く。前方は最悪。
- 特異性のあるスタイルを後ろに持ってくるということは、シンプルなスタイルほど先に書くということ。「デザインの解像度」を上げていくやり方のほうがうまく機能する。
いずれも「負の遺産」にならないように注意する。
12. 可能な限り!important
しない
// Unless it's a truly important.
13. 可能な限りハックしない
// There is always another way.
14. 変数をデザインガイドとして活用する
サイト内でバラツキが少ない方がデザイン的に良いとされるものがあります。これらは変数化して利用することでデザインガイドにもなり、デザイン変更にも強くなります。
- 文字サイズ
- 文字色
- 背景色
- フォントファミリー
- そのほか定数となるもの
$font--medium: 1rem
$font--small : 0.875rem
$color--text: #333
$color--link: #08c
$font--medium = 1rem
$font--small = 0.875rem
$color--text = #333
$color--link = #08c
また、Stylusは透過的に変数を処理できるので、さらにナチュラルにも書けます。
blue = #08c
.some-link
color blue
デザインガイドに従わない場合は変数名を使わずに定義します。
blue = #08c
.some-link
color #06c
15. CSSファイルを分割するメリットはほとんどないので一つにまとめる
やんごとなき理由がない限り、CSSは分割しない方がメリットが大きい。
やんごとなき理由:
- IEが許容するセレクタ数の上限に達した(4095個/1ファイル)
- デザインのテーマがそもそも違う(例:サブサイト)
- デバイス種別ごとにマークアップを出し分けていて、共通点が少ない
- ユーザーがテーマファイルを切り替えられる
1ファイル化のメリット:
- HTTPリクエストを減らせる
- 詳細度の管理が容易
- ファイルのロード順に伴うトラブルがない
ブラウザからすればCSSはただの宣言書なので、CSSファイルが複数あっても上から順に評価されるだけ。分けることによる機能的なメリットはまったくない。まとめましょう。
16. 追記
最後までお読みいただき、ありがとうございました。
もう少しまとまった内容をこちらに追記いたしましたので、あわせて読んでいただけると幸いです。