CSS ではできないこと

この記事について

NSEG Advent Calendar 2015 の 22 日目の記事です。
2日目の CSS Bird や8日目のサンプルコードで学ぶ CSS プログラミングの基本テクニックでは CSS でなんでもできそうな記事ばかりだったので、今日は CSS でできないことについて書いてみます。(今日のは短いです)

親要素、兄要素でしか絞り込むことができません

CSS では他の DOM 要素との関係で絞り込むための、

  • Descendant combinator ( body div )
  • Child combinator ( body > div )
  • Next-sibling combinator ( div + div )
  • Following-sibling combinator ( div ~ div )

がありますが、これはいずれも、右側の要素に対して「親」または「兄」の要素で絞り込むためのセレクタです。

つまり、チェックボックスで状態を管理する場合、その状態にしたがって表示を変化させることができるのは「弟」または「子」要素のみで、CSS では「親」や「兄」に影響を与えることはできません。 CSS Bird のようなアクションゲームでは、当たり判定のための子要素を用意しておいて、「子どもの .enemy 要素に :hover したら、親の #game-over を表示させる」というようなことができると嬉しいのですが、そういったことはできないのです。サンプルコードで、「DOM の先頭に INPUT 要素が兄弟として並ぶ」形になっていたのはこのためです。

ちなみに、Selectors Level 4 の Editor's Draft では、:has() という「セレクタにマッチする子や孫を持っている要素」を表現するための擬似クラスが含まれていて、これを使うと「#game-over:has(.enamy:hover) { display: block }」のように子要素から親要素に影響を与えるように CSS も書けるようになりそうです。

状態は DOM 構造に従ってしか伝播しません

CSS では :hover などの状態は DOM 構造にしたがってしか伝播しません。例えば次のような CSS があったとき、

「#div2」が「#div1」子要素になっていれば、「#div2」の :hover が「#div1」に伝わります。

しかし「#div1」と「#div2」が兄弟要素の場合には、見た目は同じでも「#div2」の :hover は「#div1」には伝わりません。

また逆に「#div2」が「#div1」の子要素になってさえいれば、見た目としては重なっていなくても「#div2」の :hover は「#div1」に伝わります。