やあ、調子はどうだい?
今日も元気に負債まみれのCSSと格闘していることだろう。
今回は、CSSのセレクタ周りでも「名前は知ってるけど、実務でどこまで正確に挙動を理解して使ってる?」と聞かれると、ちょっと冷や汗をかきそうなやつを取り上げよう。そう、`:only-of-type`疑似クラスだ。
チュートリアルレベルでは「親要素の中で、その型が唯一の時にヒットするんでしょ?」なんてサラッと流されがちだが、実際のプロダクションコードでこれを雑に使うと、予期せぬスタイリングの崩壊を引き起こして夜中にSlackが鳴り響く原因になりかねない。
今日は、この`:only-of-type`の仕様の深部、ブラウザの裏側の事情、そして現場で本当に使えるスマートな活用法を、シニアの視点からたっぷりと授けよう。
—
1. `:only-of-type` とは何か?(仕様の正確な理解)
まず大前提として、公式的な仕様の定義を確認しておこう。
`:only-of-type`は、「親要素の持つ子要素の中で、指定された『タグの型(type)』を持つ要素が、文字通り『世界にただ1つだけ』存在する場合にのみ」マッチする構造的疑似クラスだ。
ここで絶対に勘違いしてはいけないのが、「親の中の総子要素数が1つ」という意味ではないということだ。あくまで「そのタグの型ごとのカウント」が1つであるかどうかが判定基準になる。
よくある勘違いの例
以下のHTML構造を見てほしい。
先頭の段落
末尾の段落
ここで `.card p:only-of-type` と書いたとする。さて、このスタイルは適用されるだろうか?
……答えは 「どちらにも適用されない」 だ。
なぜか? 親である `.card` の中には、`
`タグが2つ存在しているからだ。例えその間に全く関係のない `
` という型の要素」を数えており、それが2つあると認識した時点で、`:only-of-type` の条件(唯一であること)から外れてしまう。
—
2. ブラウザは裏側でどう処理しているか?
我々が書いたCSSは、ブラウザのレンダリングエンジン(BlinkやGeckoなど)によって解釈され、DOMツリーに対してマッチング処理が行われる。
このとき、`:only-of-type` が現れると、ブラウザは少しだけ面倒な計算をする。
DOMノードを走査する際、ブラウザは以下のようなステップを踏んでいる。
1. 対象となる要素(例: `
`)に到達する。
2. その親要素(Parent Node)の参照を取得する。
3. 親要素が持つ子リスト(ChildNodes)の中から、「自分と同じタグ名(LocalName)」を持つ要素をすべてフィルタリングしてカウントする。
4. そのカウント数が「ちょうど1」であればマッチと判定し、スタイルを適用する。
つまり、DOMの兄弟要素が多ければ多いほど、またDOMツリーが深ければ深いほど、この「同型のフィルタリングとカウント」のコストが微妙に累積していく。とはいえ、現代のブラウザの最適化エンジンの性能をナメてはいけないので、パフォーマンス上のボトルネックになることは滅多にない。
ただ、ここでエンジニアとして意識すべきなのは、「HTMLの構造変更に対して非常にデリケートなセレクタである」という点だ。
—
3. 実務で使える!キレイなサンプルコードとユースケース
「じゃあ、一体いつこれを使うんだよ?」という話だよね。
実務において、`:only-of-type` が真価を発揮するのは、「CMS(WordPressやヘッドレスCMSなど)から出力される、構造が動的に変わり予測しづらいコンテンツエリアのスタイリング」や、「コンポーネントのフォールバック・単一要素のレイアウト調整」だ。
コピペしてそのままブラウザで動かせるコードを用意した。じっくり見てほしい。
お知らせカード A
この記事は単一の要約文のみで構成されています。(スタイリングが変化します)
お知らせカード B
1つ目の段落です。通常のテキストスタイルが適用されます。
2つ目の段落です。こちらも通常のスタイルです。
—
4. シニアから後輩へ送るベストプラクティスと注意点
最後に、現場でこの疑似クラスを扱う上での「心構え」を伝授しておこう。
1. クラス名(BEMなど)との使い分けを誤るな
もしその「唯一の要素」に特定のスタイルを当てたいことが最初から分かっているなら、CSSの構造的疑似クラスに頼るよりも、HTML側に修飾クラス(例: `.card__text–solo`)を付与する方が、保守性の観点からは100倍安全だ。`:only-of-type` はあくまで「後から構造が動的に変わる、あるいはテンプレート側でクラス制御が面倒な箇所」の救世主として使うべきだ。
2. `:only-child` と混同するな
兄弟要素の中に他のタグ(例えば `` や `
3. デザイナーとの共通認識
「要素が1個の時と2個以上の時でデザインが変わる」という仕様は、往々にしてデザインカンプから抜け落ちがちだ。フロントエンド側で勝手にこのセレクタを使って動的にデザインを変えるときは、あらかじめデザイナーと「1つの場合のフォールバック仕様」について握っておくのが、シニアとしてスマートな立ち回りだ。
基礎的なセレクタほど、深く理解しているとコードの行数を削れるし、無駄なJavaScriptの条件分岐を排除できる。ぜひ、今日のコードを明日の案件のレイアウト調整に役立ててみてほしい。
それじゃ、また次の現場で会おう。

コメント