:hoverしている要素の直前の要素の指定をCSS4の!符号で妄想した

※これは「そうなったらいいなあ、こういうふうにできたら僕は都合がいいなぁ」という妄想であり、CSSの仕様を解説する記事ではありません

CodePenにあった Stairway NavというサンプルがFlashぽくて格好よいのだけど、:hoverしてる前の要素の取得にJavaScriptを使っているのを見て、これがCSSだけでできたらいいのにと思った。 2012/8/23時点のSelector Level 4のWorking Draftでももちろんそんな都合のいいセレクタは存在していない。あったらいいのに。

ということで妄想してみた。やるとしたらE! > Fで「Fを直接の子要素にもつE要素」をスタイリング対象にできるという「!」マークを使う。

<ul>
  <li>たまご</li>
  <li>ごはん</li>
  <li>しょうゆ</li>
  <li>かつおぶし</li>
  <li>食べたい気持ち</li>
</ul>

このようなHTMLがあったとして、

li! + li:hover{...}

このように書けば、「li:hoverを隣接要素に持つli」という解釈になり、見た目として:hoverしているliの直前のliをスタイリング対象にすることができるのではないだろうか。さらに、:hoverの2つ前のliを対象にしたい時はこんな具合か。

li! + li + li:hover{...}

:hoverしたli以前の全てのliを対象にしたい場合はこうか。

li! ~ li:hover{...}

実現できたら素晴らしいが、それにしてもli要素に!マークは視認性が悪すぎる!

......妄想は以上です。

ところでこの!マークはなんて呼べばいいのだろう。 冒頭リンクのWorking Draftだと「Determining the Subject of a Selector」として解説されている。Subjectは英文法SVOのSだから、「セレクターの主部の決定」と訳せる。そうなると「主部決定符号」とか? なんだかしっくりこない。プロパティを適応する対象を決定するのだから「対象符号」と呼ぶのはどうだろうか。うん、それがいいと思う。

対象符号は 2011年のWorking Draftでは「$」マークで要素の前に設定されていたけど、「!」に変わり付加位置も要素の後ろに変わった。そのおかげでこんなISSUがあがっている。

Should the exclamation mark be prepended or appended to the subject? Or both? Or prepend two, to avoid the "! = not" issue?

抄訳: !マークは対象要素の前と後ろ、どっちにつける? 前と後ろの両方に付ける? もしくは、"◯◯でない" という意味にならないように要素の前に2つ付ける?

要素を!で挟む形になるのも気持ち悪いし、!を2個つけるのも気持ち悪い。

 $E > F {...} /* Old Draft */
 !E > F {...} /* looks like "!=not" */
!E! > F {...} /* OMG */
!!E > F {...} /* is mean not not-E? */
 E! > F {...} /* Working Draft in 2013-5-2 */

「!=not」はプログラムやる人にはお馴染みのやつで、そう言われればたしかに違和感ある。ちなみにE:notという擬似クラスセレクタはすでにある。

最初の「$」でいいじゃんと思っていたけど、Sassとの衝突を避けるため別の記号にしたんだっけか。主要な記号はそういったプリプロセッサで使われているから上手いの考えるのが難しそう。かと言って!importantみたいなのは止めて欲しい。 :parentなんていう書き方を妄想してる人もいた(2010/10/21)。:parentでは隣接セレクタには対応できない。倣うなら:siblingだろうか。つらそう。

最終的に「Determining the Subject of a Selector」はどんな仕様になるんだろう。早く使いたい。

2013/5/2にSelectors Level 4のWorking Draftが更新されているが、Determining the Subject of a Selectorについては変更はないようだ。