CSSの:emptyが効かないときは空白のtext nodeと子要素を確認する
公開日: 執筆:佐藤
CSSの:emptyは、画面で文字が見えない要素ではなく、document treeに子が一つもない要素へ一致します。見た目が空でも、開始tagと終了tagの間に改行や字下げの空白があればtext nodeができるため、:emptyは一致しません。
最初にCSSのspecificityを疑うのではなく、対象要素の中にtext nodeか子要素があるかを確認してください。HTMLを本当に空にできるなら、:emptyは単純な空要素の表示制御に使えます。
:emptyは子を一つも持たない要素へ一致する
W3CのSelectors Level 3は、:emptyを子が一つもない要素に一致するpseudo-classと定義しています。空かどうかへ影響するのは、element nodeと、長さが0ではないtext nodeなどのcontent nodeです。commentとprocessing instructionは影響しません。
次のHTMLでは、p要素に子がないため、.notice:emptyが一致します。
<p class="notice"></p>
.notice:empty {
display: none;
}
class名が同じでも、要素内に文字か子要素があれば一致しません。
<p class="notice">受付を終了しました。</p>
<p class="notice"><span></span></p>
二つ目のspanが空でも、pにとっては子要素です。:emptyは、子要素の中身まで調べて「実質的に空」と判断するselectorではありません。
改行と字下げもtext nodeになる
次のpは画面上で文字が見えませんが、:emptyには一致しません。
<p class="notice">
</p>
開始tagの後の改行と終了tagの前の改行は、長さを持つ空白のtext nodeになります。読みやすいように入れた改行でも、document treeでは子です。
templateから空の要素を出す場合は、次のように開始tagと終了tagを続けます。
<p class="notice"></p>
ただし、出力する内容がないとtemplate側で分かるなら、wrapper自体を出力しない方が明確です。:emptyへ頼って不要なmarkupを隠すより、contentの有無を判断する処理とHTML出力を同じ場所で管理できます。
commentは空判定へ影響しない
commentは:emptyの判定へ影響しません。次のpにはcommentがありますが、element nodeや長さを持つcontent nodeがないため、:emptyへ一致します。
<p class="notice"><!-- 表示内容なし --></p>
開発者toolで子を調べるときは、elementだけを一覧する表示だけで判断しないでください。空白のtext nodeはelement treeで見落としやすいため、対象要素を展開し、開始tagと終了tagの間の改行や空白も確認します。
CSSの問題とHTML出力の問題を分ける
:emptyが効かないときは、次の順で原因を分けます。
- selectorが目的の要素を指しているか確認する
- 対象要素に子要素がないか確認する
- 開始tagと終了tagの間に改行や空白がないか確認する
- commentだけなら、別のCSS ruleによる上書きを確認する
子要素かtext nodeがあれば、:emptyの条件を満たしていません。CSSの上書きやspecificityを調べる前にHTMLを直します。子が一つもないのに表示が変わらない場合は、そこで初めてruleの読み込み順、specificity、displayの上書きを調べます。
原因を混ぜると、!importantを足しても解決しません。selectorが一致していない問題と、一致したruleが上書きされる問題は別です。
:emptyをcontentの有無の判定に使いすぎない
:emptyはdocument treeの構造を選ぶselectorです。formの入力が必要か、商品説明が登録済みか、問い合わせへ返信できる状態かといった業務上の条件までは判断できません。
内容の有無によってHTML構造そのものを変えるなら、server側やtemplateの条件分岐で決めます。CSSは、出力済みの空要素へ余白やborderを残さないための補助として使います。
制作を委託する場合、実装者は:emptyのruleとtemplate出力を直せます。しかし、どの内容を「未入力」と扱い、要素自体を出さないのか、空の枠だけ残すのかはsite運営者が決める条件です。見た目の修正へ、contentの意味まで任せないでください。
最初の一手は、:emptyが効かない要素の開始tagと終了tagの間を確認することです。改行、空白、子要素のどれかがあれば、それを意図した出力かtemplate側から見直します。
関連記事

