現場のCSSアーキテクトとして、一つ核心を突いた話をしよう。
君たちが普段書いているCSS、特にセレクタの記述。「`nav ul li a`、`nav ol li a`、`header ul li a`……」なんて具合に、似たような記述を並べて、あとから「あ、ここにも適用しなきゃ」とコンマで繋いでいく。あれ、保守性の観点からは「負債の積み上げ」に他ならないんだ。
そこで今回取り上げるのが `:is()` 擬似クラスだ。これは単なる記述を短くする糖衣構文じゃない。「詳細度(Specificity)のコントロール」という、CSS設計の聖杯に近づくための強力な武器なんだ。
—
:is() が解決する「セレクタ爆発」のジレンマ
実務でよくあるのが、特定の要素がネストされた階層下で、同じスタイルを共有したいケースだ。
/ 従来の書き方:見通しが悪く、修正漏れが起きやすい /
.article-body h2,
.article-body h3,
.article-body h4 {
font-weight: bold;
color: #333;
}
/ :is() を使った現代的な書き方 /
.article-body :is(h2, h3, h4) {
font-weight: bold;
color: #333;
}
見ての通り、`:is()` は括弧の中にセレクタリストを渡すだけで、対象を一つにまとめられる。記述量が減るだけでなく、「このコンポーネント内の見出し系は全部これ」という意図がコードから読み取れるようになる。これだけで、レビュー時の認知負荷がぐっと下がるはずだ。
現場が震える `:is()` の詳細度ルール
さて、ここからが本題だ。多くのエンジニアが `:is()` を敬遠する理由、それは「詳細度がどう計算されるか分からない」という恐怖心から来ている。だが、ルールは至ってシンプルだ。
「`:is()` 全体の詳細度は、引数の中で最も詳細度が高いセレクタに準ずる」
例えば、`:is(.card, #main)` と書いた場合、このセレクタ全体の詳細度は ID セレクタ(#main)のものになる。逆に `:is(.card, div)` なら、クラスセレクタ(.card)のものだ。
失敗しないための「詳細度」サンプルコード
以下の例を見てほしい。`:is()` の中身によって、後続のスタイルが上書きされるかどうかが決まる。
/ 1. まずベースとなるスタイル /
.container p { color: gray; }
/ 2. :is() の詳細度は、引数内の最強セレクタに依存する /
/ 下記の場合、.container #highlight と同等の詳細度を持つ /
.container :is(p, #highlight) {
color: red;
}
/ 3. この記述が効くかどうかは、上の :is() の中身次第 /
highlight {
color: blue;
}
もし `:is()` の中に ID セレクタが含まれていれば、当然そこは強烈な詳細度を持つ。「とりあえず `:is()` で囲めば楽になる」と安易に使うと、詳細度のインフレを起こして後で死ぬことになる。 現場では、極力「クラスセレクタのみ」で構成するのが、CSS設計における鉄則だ。
ブラウザの裏側:パーサーはどう処理しているか?
ブラウザは `:is()` に遭遇すると、それを「展開」して処理する。実は `:is()` は、`div:is(.a, .b)` を `div.a, div.b` と展開しているのと同じだ。
ここで注意してほしいのは、「`:is()` 内で無効なセレクタが含まれている場合、そのセレクタだけが無視される」 という仕様だ。
(※ `:where()` という兄弟擬似クラスもあるが、こちらは詳細度が常に 0 だ。これについてはまた別の機会に話そう。)
実務で使いこなすためのベストプラクティス
最後に、明日からのコーディングで即採用できる構成を紹介する。BEMで設計されたプロジェクトなら、以下のような使い方が最も美しい。
/
- 複数の修飾子を持つコンポーネントの一括制御
- BEMの要素に対しても非常に相性が良い
/
.card:is(.is-active, .is-hovered) {
border: 2px solid #007bff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
/
- レスポンシブ対応の簡略化
- メディアクエリのネストと組み合わせると最強の武器になる
/
.grid-item :is(h2, p) {
margin-bottom: 1rem;
}
@media (min-width: 768px) {
.grid-item :is(h2, p) {
margin-bottom: 2rem;
}
}
終わりに:CSSは「書く」のではなく「管理する」もの
`:is()` は単なる便利機能ではない。君たちのCSSを「場当たり的なリスト」から「論理的な構造」へと進化させるためのツールだ。
コードをコピペして動くことに満足するな。そのコードが、半年後の自分や、明日一緒に働くメンバーにとって読みやすいか。詳細度のバランスは崩れていないか。そうした視点を持てるようになれば、君はもう一段上のフロントエンドエンジニアになれるはずだ。
次は `:where()` との使い分けについて語ろうか。あれを使いこなせると、CSSの設計思想が一気に洗練されるぞ。また現場で会おう。

コメント