CSSの詳細度をうまく操る

http://csswizardry.com/2014/07/hacks-for-dealing-with-specificity/

1 comment | 2 points | by WazanovaNews 約3年前 edited


Jshiike 約3年前 edited | ▲upvoteする | link

Harry Robertsがブログで、CSSのプロジェクトをうまくスケールさせるためには、詳細度の影響をうまく抑えて、メンテナンス性を高めることがポイントだと解説しています。

どれだけ思慮深くソースの順や継承関係を整理しても、詳細度がトリガーになった上書き起きると、それまでの努力が台無しになる。詳細度のタチが悪いのはオプトアウトできないこと。

であるが、その悪影響をうまくコントロールする策としては、

  • CSSにおいてセレクタとしてIDは使わないこと。クラスを使うことを上回るメリットはない。そもそも、IDでできることはクラスでできる。IDは再利用が効かないし、詳細度がとにかく高過ぎる。クラスを無限につなげても、一つのIDの詳細度にはかなわない。
  • セレクタを不必要にネストさせないこと。.header .header-nav {}は、セレクタの詳細度を意味なく2倍にしてしまうので、もし.header-nav {}がワークするなら.header-nav {}を使うべき。
  • 本当に必要な場合以外は要素に対するセレクタを書かないこと。ul. nav {}は、. navclassを使える箇所を制限するだけなく、意味なくセレクタの詳細度を上げてしまうので、. nav {}がワークするなら. nav {}を使うべき。
  • クラスを多用すること。詳細度が低いし、色々なところで使い回すことができ、再利用もしやすいので、理想的なセレクタと言える。

結論として、

CSSにおいてIDを使うべきというケースはない。HTMLでフラグメント識別子として使ったり、JavaScriptでフックとするのはあり。

一方、極力使うべきでないが、どうしても他に選択肢がなかったときの回避策として、二つの事例を取り上げています。

1) 属性セレクタへの変換

ページにサードパーティのウィジェットを組み込む際、

<div id="widget">
     ...
</div>

とスタイルしたいが、HTMLではIDの替わりにクラスで編集はできないので、

#widget {
     ...
}

とすると、CSSにIDを置いてしまうことになる。よって、

[id="widget"] {
     ...
}

とすれば、属性セレクタとすることで対処できる。属性セレクタとクラスセレクタの詳細度は同じなので、IDに基づいてDOMを選択しても、クラスを超える詳細度にはならないようにできる。

このテクニックには。再利用が効かないという課題はある。IDをクラスのマークアップで書き換えることができなくて、他に選択しがないときだけ、このテクニックを使うようにすること。

2) セレクタを重ねて詳細度を調整

このサンプルでは、17行目の.box a {}でのカラー指定が、22行目の.btn {}を不本意に上書きすることで、ボタンのカラーがバックグランドと同じになってしまっている。

!importantを使っての修正は、CSSファイルの規模が大きくなるとメンテ地獄になるので避けたい。

.btn {}新たなセレクタを追加してしまうこともできるが、都度セレクタの種類を増やすことで詳細度を調整する方法では、将来のメンテが大変になる。

そこで、このように.btn.btn {}とすると、位置や文脈にかかわらず詳細度を調整できて、管理するセレクタの数も増えないのでメンテもしやすくなる。

#css

Back