ID使っても別に問題ない

CSSでID使うの良くない……どころか、ID使うのはゴミクズカスみたいな風潮で辛い。その根拠はいくつかあり、それらはCSSだけをただそのまま書く場合には納得出来ないこともないかなーと思うので余計に辛い。特にOOCSSのようなアプローチではIDは混ぜるな危険。だからといってIDを使わないのがベスト・プラクティスなわけじゃない。

CSS Lintの利用が広まり、これがID使うなって怒るのも原因の一端な気がする。Disallow IDs in selectorsではIDの問題点として以下のようなものを取り上げている。

However, IDs have a downside: they are completely unique and therefore cannot be reused.

つまりユニークなため再利用できないというマイナスの面がある、と。確かに再利用できない。でもこれはマイナスの面では決してない。ユニークで再利用できないからこそ、そのウェブページでユニークな要素を特別に表現できるということだ。

そもそもCSSのセレクターはクエリーであり、どういう要素を選択するのかを表現するものだ。つまりセレクターを読めばそのルールセットに含まれるスタイルがどういう要素に適用されるのかすぐわかるというのが理想的だと思う。クラスですべてを表現するのがCSSに向いているというのなら、なんのためにあの柔軟なセレクター機能が仕様で定義されブラウザーで実装されているのか意味がわからない。

.callout a {
  color: #369;
}

というようなわかりやすいが曖昧なクラス名よりも、

#logo a,
article h2 a {
  color: #369;
}

というような複雑だけど明示的なセレクターの方が、適用される要素がわかりやすいはずだ。これはつまりCSSからHTMLの見通しが良いということになる。このCSSだけで以下のようなHTMLが楽に想像できる。

<body>
  <header>
    <h1 id="logo"><a href="/">Example</a></h1>
  </header>
  <article>
    <h2><a>Article Title</a></h2>
  </article>
</body>

このHTMLならばCSSでどうセレクターを書くかも明確になる。もちろん他に書きようがないからだけど、HTMLの要素とCSSのセレクターとの関係性に曖昧さが含まれないということでもある。HTMLとCSSは密接に連携して機能するものなので、HTMLとCSSがそれぞれわかりやすかったりしてもあまり意味はない。HTMLからCSSが、そしてCSSからHTMLが把握できて初めて良いHTMLとCSSと言えると思うし、僕はそういうHTMLとCSSが好きだ。

かなりアレではあるけど、CSSでクラスを使ってすべてを選択するのはHTMLでdivspan要素ですべてをマークアップするようなものではないか、というような思いもある。IDを使うべきところではIDを、クラスを使うべきところではクラスを使う必要があるはずだ。

IDの利用

CSSにおいてIDをセレクターで使う例としては、以下のようなものが具体的に挙げられるだろう。

  • ユニーク、かつ現状のセレクター実装ではうまく表現できない要素
  • スクリプトで利用するために振られたものの再利用

前者はクラスでも良いけど、IDを使えばユニークなことを保証できる。

後者は単なるセレクターの簡略化や効率化という話ではなく、ルールセットが対応する要素をより明確に指定するということだ。スクリプトで利用するためにIDを振られた要素というのは、ウェブページの中で特別なコンテンツである事が多い。IDを再利用した方がその要素に含まれるコンテンツが特別であることをCSSからも表現できるだろうし、良い方向にそのカスケーディングにおける強さが働くだろう。

再利用性とメンテナンス性

IDはユニーク、かつCSSのカスケーディングにおいて強いので、特に再利用性とメンテナンス性という点では問題が起きやすい。共通のルールを切り出して共有し再利用することが出来ないので、同じルールを色々な場所に書かざるを得ずメンテナンス性が著しく低下する。またセレクターの強さの関係上、モンキーパッチのようなことも行いにくく、ちょくちょくインライン・スタイルや!importantが必要になったりと中々厳しい。

CSSにおいてはほぼそういうものといって間違いなく、この点を重視してIDの利用を避けるというのもひとつの選択だろう。

ただし、こういった再利用性とメンテナンス性における問題は、Sassのようなルールをモジュール化してどんなセレクターにも効率的に取り込めるCSSプリプロセッサーで多くは解決できる。Sass 3.3ならプレースホルダー・セレクターを定義して、@extendするだけ。CSSプリプロセッサーの学習コストはかなり高く万人に勧められるものではないが、一考には値すると思う。

セレクター数の増加

Internet Explorer 9以下のバグで、1ファイルに4096以上セレクターが書けないというものがある。このバグを根拠に、セレクターの効率化のため再利用可能なクラスのみを使うという主張もたまに聞く。しかし、なんら間違ったことをしていないのにバグに対応するためCSSの書き方を変えるというのはおかしい。単純に4096以上になる危険があるのなら、CSSファイルを適当に分割するツールを採用すれば良いだけで、CSSに対する姿勢を変更するべきようなことではない。

CSSハックの利用なども含め、CSSの書き方に強い制限を加えるのは現実的な解であるが、それはベスト・プラクティスではない。普通に書いて分割したり、別に管理し連結したりするべきことで、その作業は自動化すべきことだ。幸い現在はそういったツールが探せばある時代なので、ツールで最適化というのが望ましい。

BEM

BEMで書くなら、それはそれで良い。BEMはクラスを多用するけど、それに厳しい命名規則を適用させることによってセレクターで厳格に要素の表現を行えるようにしたもの。そのためセレクターから適用される要素が自明になる。モジュール化した複数のクラスを組み合わせるようなケースとは違い、BEMのクラスに曖昧さはまったくない。

厳格な命名規則によりHTMLの簡潔さは失われるが、その代わりにCSSの保守性は上がる。BEMはそういう現実的な妥協と選択を行ったものに過ぎず、方向性としてはIDやHTMLの文書構造を利用したセレクターでCSSを書くのと同じ。そのあたりがOOCSSユーザーに違和感を与える理由でもある。


別にユニークな要素には無理矢理にでもIDを使えと言っているわけじゃない。HTMLでは必要最小限のマークアップで済まし、CSSのセレクターの書き方の工夫でスタイルと要素を関連付ける、というのが基本であるということ。そして必要ならIDとクラスをうまく使い分けて追加するということだ。そうすることによってのみコンテンツにぴったりと誂えられたHTMLとCSSでウェブサイトを作ることができる。

あえてIDを使わないという選択はその上でなされるべきだ。例えばバックエンド側にHTMLが握られているようなケースでは、あえてHTMLとは独立してビジュアル・デザインを行いたいこともあるだろう。そういう時はHTMLとCSSに明確な繋がりがない方が小回りがきくので、クラス中心でIDを使わない方がCSSは書きやすくメンテナンスもしやすい。つまりウェブサイトの設計段階での選択であるのが望ましい。

こういった前提なしにIDを使わないことがあたかもベスト・プラクティスであるかのように広まってしまっているのはあまり良いことではないのではないかと思う。IDはCSSにおいてはいわばその使いづらさに一定の意味があると言えると思うので、そのことを理解し適切に使ってやるべきものだ。