Error: I'm afraid this is the first I've heard of a "$flavour" flavoured Blosxom. Try dropping the "/+$flavour" bit from the end of the URL.

Wed, 23 Aug 2006

カスケーディング重要

ひとくちにCSSと言われますが、略さないで言うとCascading Style Sheetsであり、つまりカスケーディングするという特徴を備えたスタイルシート、ということになります。じゃあカスケーディングって何? と問われてみると、ふだんは直感的にCSSを使っているものの、言葉で説明するとなると難しいものです。

そもそもcascadingというのが日本人には難しい言葉です。英語のcascadeの元の意味を説明するなら「階段状になった滝」となるのだと思いますが、それが動詞化するとなると、なんかそれっぽい(=階段状になった滝のような)動作、としか言いようがなく、どうにもぴったりとくる日本語訳が無さそうなので、ここではそのままカスケーディングと書くことにします。

取り敢えずcascadeのイメージを湧かせるため、以下の画像を眺めてみてください。

* * *

さて、CSS講話CSSの優先順位の解説と、それに対するInternet Exact CourseのCSS講話に関して:メモランダムでの指摘について。

※註: CSSの優先順位は2006年8月23日に修正されています。以下の記事は修正前の解説について述べたものです。

p{
 color:#000;
}
em{
 color:#f00;
}
<p>言論の自由が<em>無責任な発言を助長してしまった</em>と云う事は覚えておくべきだろう。

このCSSとHTML断片について、CSSの優先順位では以下のように説明されています。

この時、em要素の色は黒(#000)になるのか、それとも赤(#f00)になるのかが問題になります。これがプロパティの衝突です。CSSの仕様では、こう云う形でプロパティが衝突した時は後で指定された方を優先するとされています。詰り、emセレクタへの指定が後にある為、em要素のスタイルはそちらが優先されるのです。従って、em要素の色は赤(#f00)となります。

実際に書いてブラウザで見ていれば気付いていたと思うのですが、em要素のスタイル宣言を先に書いてもem要素内の文字は赤になります。(テスト)

この説明に対して、Internet Exact CourseのCSS講話に関して:メモランダムでは「em要素が赤色になるのはemがpの子ノードだから」と述べているのですが、その説明も十分でないように思います。何故かというと、仮にHTMLでemが親要素・pが子要素と逆転していたとしても、やはりem要素内の文字は(子のp要素の部分を除いて)赤くなるので。

em要素の文字が赤くなる根拠については、CSS2仕様の6.4.1 Cascading orderの1項の記述が該当するかと思います。参考のため日本語訳より引用。

1. 問題の要素及び特性に適用されるすべての宣言を対象メディア型について発見する。関連選択子が問題の要素と一致する場合,宣言が適用される。

要するに、em要素にマッチするセレクタのついたスタイル宣言があるならば、まずはそちらを適用しますよ、という話だと思います。

もし仮にem要素のスタイル宣言が無ければ、文字色は親要素から引き継がれたもの(この場合はたまたま親のp要素で指定されていた黒)が使われるでしょう。この働きがいわゆる継承です。しかしひとたびem要素に対する宣言が存在すれば、なにはなくともまずそれを適用する――これがCSSにおけるカスケーディングの第一原則です。

さてここでcascadeの元の意味、つまり階段状になった滝のイメージを思い出してみてください。「流れ落ちる水」を「継承」、その途中に設けられた「段」をいま述べた「カスケーディング」に当てはめてみると……なぜCSSがcascadingするstyle sheetなのかが分かるような気がしてこないでしょうか。(しなかったらすみません)

また、今度はCSSの優先順位の説明に戻ってみると、挙げられた例では、em要素にマッチするスタイル宣言は一つだけなので、「プロパティの衝突」なるものは実際には発生してないことになります。なのでCSSの例がそもそも適切でなかったのだと思います。

或る要素にマッチする重複した宣言の例を挙げるのであれば、単純に以下のようなCSSでよいと思います。

em {
  color:#000;
}

em {
  color:#f00;
}
* * *

ちなみに、CSSの優先順位では「優先順位の入れ替え」の記述も訂正が必要かと思います。(先に述べた通り、もともと衝突しない宣言同士なので、!importantで優先順位が入れ替わるようなことも起こりません)

#