スタイルシートの a:hover と a:active の順序

訳あって、スタイルシートについて調べています。
スタイルシートに動的疑似クラスを書く時の順序が重要であることはみんな知っていると思う。

復習

復習、こういう順序で書くべき。

    a:link    { color: red }
    a:visited { color: blue }
    a:hover   { color: yellow }
    a:active  { color: lime }

こういう順序で書くべきではない。(「書いてもいいけど、たぶん、あなたの思った通りにはならないと思うよ」という意味で。)

    a:link    { color: red }
    a:visited { color: blue }
?   a:active  { color: lime }
?   a:hover   { color: yellow }

上のふたつの例では、最後の 2 行だけ、すなわち a:hover と a:active の順序だけが異なっています。他は一緒。

「ページをブラウズしているユーザが、リンクの上にマウスポインタを持ってきている間 (hover) はリンクの色を黄色にしたい。そして、ユーザがそのリンクの上でマウスのボタンを押している間 (active) はリンクの色をライム色にしたい」

そう考えているのなら、ひとつ目の例で示した順序で書くべきであって、ふたつ目の例で示した順序で書くべきではない。
さもないと、リンクの上にマウスポインタを持ってきた時にはちゃんとリンクが黄色になるのに、そこでマウスのボタンを押した時にはリンクの色が変化しない、ライム色になってくれない、という事態を引き起こす。

なんで?

なぜそうなるのか、を理解するために理解しなきゃならないこと。

  1. ユーザが a 要素の上でマウスのボタンを押している間は、その a 要素は hover 状態であり、かつ、active 状態である
  2. 規則が競合する場合は(他のいろいろな値*1の計算・比較の結果が同じなら)、後から指定した規則のほうが、先に指定した規則に勝つ

というわけで、「hover 状態でもあり active 状態でもある」という場合には、どっちの規則がより後ろに書いてあるのかが問題を解く鍵となるわけです。
上のふたつ目の例で示したように、a:hover を最後に書くと、a:hover が勝ってしまい、マウスのボタンを押していようが押してなかろうが、hover 状態の色が適用されてしまう、というワケです。

参考文献

Cascading Style Sheets, level 2 revision 1 (CSS 2.1 Specification)
http://www.w3.org/TR/CSS21/

多分これがちゃんと出来上がった Specification としては最新の CSS21 というヤツ。w3c に行くと、CSS3 もあるけれど、そっちはまだ工事中。
CSS21 の翻訳は見つけられなかったけど、CSS2 の翻訳はあった。

Cascading Style Sheets, Level 2
http://www.y-adagio.com/public/standards/tr_css2/toc.html

この翻訳の時点での原文はこちら

Cascading Style Sheets, level 2 (CSS2 Specification)
http://www.w3.org/TR/1998/REC-CSS2-19980512/

気になった点

翻訳が間違っているのか、もともとの英文が間違っているのかわからなかったんだけど、ちょっと気になった部分がある。
「5.11.3 動的擬似クラス(:hover, :active, 及び:focus)」という部分の、この文。

A:link    { color: red }    /* unvisited links */
A:visited { color: blue }   /* visited links   */
A:hover   { color: yellow } /* user hovers     */
A:active  { color: lime }   /* active links    */

A:hover規則の'color' 特性を段階化規則が隠蔽する場合があるため,A:hoverはA:link及びA:visited規則の後に配置されなければならない点に注意すること。同様に,A;activeは,A:hoverの後に配置されるため,活性色(ライム色)は,利用者がA要素を活性化する場合にも,その上に停止する場合にも適用されることになる。

この文章だと、単に hover しただけでリンクの色がライム色になっちゃうような感じがしちゃう。
原文。5.11.3 The dynamic pseudo-classes: :hover, :active, and :focus

A:link    { color: red }    /* unvisited links */
A:visited { color: blue }   /* visited links   */
A:hover   { color: yellow } /* user hovers     */
A:active  { color: lime }   /* active links    */

Note that the A:hover must be placed after the A:link and A:visited rules, since otherwise the cascading rules will hide the 'color' property of the A:hover rule. Similarly, because A:active is placed after A:hover, the active color (lime) will apply when the user both activates and hovers over the A element.

私なりに訳してみる。

A:hoverをA:link及びA:visited規則の後ろに配置しなければならない事に注意してください。さもないと、段階化規則によってA:hoverの'color'プロパティが隠蔽されてしまうからです。同様に、A:activeをA:hoverの後ろに配置したので、利用者がA要素の上空に位置し、かつ、A要素を活性化している時には、活性色(ライム色)が適用されます。

英文の訳として正しいかどうかはわからないけれども、CSS の意味的には、こういうことになると思う。


CSSシークレット ―47のテクニックでCSSを自在に操る

CSSシークレット ―47のテクニックでCSSを自在に操る

*1:重要性とか起点とか固有性とか