IE 7 と Firefox 1.5.0.7 と Opera 9.02 の擬似要素の取り扱い

http://hxxk.jp/2006/10/27/2105

記事データ

投稿者

望月真琴

投稿日時

2006-10-27T21:05+09:00

タグ
概要

IE 7 は、 :first-letter 擬似要素は、元の要素の子ノードとして独立して扱うようです。よって、 IE 7 の挙動もまあ腑に落ちるなあという結論になりました。 Firefox や Opera は :before 擬似要素 / :after 擬似要素の実装の関係で :first-letter 擬似要素も同じノードに含んで扱っているような印象。

リプライ

5 件のリプライがあります。

記事本文

仕様は最後まで読みましょう

IE 7 の :first-letter 擬似要素の font-size の算出IE 7 の :first-letter 擬似要素の font-size のカスケーディングであれこれ悩んでいる IE 7 と :first-letter 擬似要素の問題ですが、はてなブックマーク - 徒栞の北村さんのはてなブックマーク - hxxk.jp - IE 7 の :first-letter 擬似要素の font-size のカスケーディングでの :first-letter擬似要素を用いた時の"fictional tag"は http://www.w3.org/TR/REC-CSS2/selector.html#x57 にあり。/ 最後の図の"IE 7"と"Firefox や Opera"は逆のような というコメントで再度仕様を読みました。

実は http://www.w3.org/TR/CSS2/selector.html#first-letterhttp://www.w3.org/TR/CSS21/selector.html#first-letter は見てはいたんですよ。 ただ、最初の段落だけ読んで「うーんやっぱり要素ツリーのことについてはあまり触れていない ? 」と勝手に判断してその後まで読んでいないという。 最後まできちんと仕様は読みましょう、ということで。 これは私の怠慢に他ありません。

......ところで、以前も北村さんには言ったことがありますが、「これはブックマークコメントじゃなくてコメント欄で指摘してもらえるとありがたいなあ」と思う類のご指摘だと思いました。 私は被ソーシャルブックマーク状況をチェックする方法のまとめという記事を書いていることからも分かる通り、ソーシャルブックマークによるコメントでのご指摘も、 hxxk.jp 内のコメント欄のご指摘も同じように汲み取ります。 でも、もし同じような疑問を持っていて IE 7 の :first-letter 擬似要素の font-size のカスケーディングに辿り着いた方がいらっしゃって、かつブックマークコメントのことを知らない、あるいはそこまで気が付かないというケースがあるかもしれません。 記事を読んでの感想やメモのための要約だったらともかく、指摘や助言に類するものは直接コメント欄に書いてもらった方がありがたいなあ......と贅沢なお願いをしてみます。

:first-letter 擬似要素の要素ツリー

個人的なやりとりはさておき、示された仕様の部分を見てみましょう。

<P>
<SPAN>
<P:first-letter>
T
</P:first-letter>he first
</SPAN> 
few words of an article in the Economist.
</P>

Note that the :first-letter pseudo-element tags abut the content (i.e., the initial character), while the :first-line pseudo-element start tag is inserted right after the start tag of the element to which it is attached.

これが CSS2Selectors - The fictional tag sequence is: の仕様で、次に引用するのが CSS 2.1Selectors - The fictional tag sequence is: の仕様です。

<P>
<SPAN>
<P:first-letter>
T
</P:first-letter>he first
</SPAN> 
few words of an article in the Economist.
</P>

Note that the :first-letter pseudo-element tags abut the content (i.e., the initial character), while the :first-line pseudo-element start tag is inserted right after the start tag of the block element.

「その :first-letter 擬似要素が与えられた要素の開始タグの直後」か「ブロックレベル要素の開始タグの直後」かという表現の違いがありますが、 CSS2 も CSS 2.1 も 「元となる要素の開始タグの直後に :first-letter 擬似要素の開始タグが現れる」 と示されています。

......ということはですよ、この引用した例のような構造ならば、 CSS はどのように書いているかのような

* {
    font-size: 100%;
}

h2 {
    font-size: 2em;
}

h2:first-letter {
    color: #ddd;
    font-family: Arial , Verdana , sans-serif;
}

という「ユニバーサルセレクタで font-size を指定していて、 :first-letter 擬似要素で font-size を指定していない」ようなスタイルならば、 IE 7 のようにユニバーサルセレクタにマッチしてその font-size を適用する方が正しい実装で、 Firefox や Opera のように勝手に (?) h2 要素にマッチさせて font-size: 2em; としてしまう方が変な実装、ということになるのでしょうか ?

図にしてみようの補足

図にしてみようで作ってみたツリー図ですが、説明が足りなかったみたいでした。 まず説明する前に同じ図を掲載しますね。 使い回しとか言わない。

IE 7
  • h2:first-letter 擬似要素にマッチしなければユニバーサルセレクタにマッチ
Firefox や Opera
  • h2:first-letter 擬似要素にマッチしなければ h2 要素にマッチ

これは図の中で垂直方向に並んでいる要素は、より下の要素は上の要素の子要素になっていることを表しています。 また、同じ要素を親に持ち、水平方向に並んでいる要素はより左の方の要素が HTML 中で先に現れることを表しています。 図の元にした HTML ソースコードに、更に :first-letter 擬似要素を展開したと仮定して表すと

<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
  <head profile="http://purl.org/net/ns/metaprof">
    <title>MOMENT</title>
  </head>
  <body>
    <h1>MOMENT</h1>
    <div class="section entry" id="entry-1650">
      <h2><h2:first-letter>2</h2:first-letter>006-10-19T12:15:21+09:00</h2>
      <p>む、とあるメールで IE7 の正式版リリースの報せが。やっぱりもう出ちゃったのかあ......</p>
    </div>
  </body>
</html>

となりますが、図では head 要素や div 要素を抜いてしまっていたため、逆に分かり辛くなっていました。 そこで、もう一度図を作り直してみました。

IE 7
  • h2:first-letter 擬似要素にマッチしなければユニバーサルセレクタにマッチ
  • h2:first-letter 要素での font-size の指定が無ければ、 h2 要素にて font-size が指定されていてもユニバーサルセレクタにマッチしてその font-size を適用する。
  • h2:first-letter 要素にて font-size: 150%;font-size: 2em; の指定があれば、 h2 要素を親要素として、その font-size の値を元に値を算出する。
Firefox や Opera
  • h2:first-letter 擬似要素にマッチしなければ h2 要素にマッチ
  • h2:first-letter 要素での font-size の指定が無く、 h2 要素にて font-size が指定されていれば、 h2 要素の font-size を適用する。 ( h2 要素でも font-size の指定が無ければ、ユニバーサルセレクタにマッチしてその font-size を適用する。 )
  • h2:first-letter 要素にて font-size: 150%;font-size: 2em; の指定があれば、 h2 要素を親要素として、その font-size の値を元に値を算出する。

これでどうでしょう ? 要するに、 IE 7 は h2:first-letter 擬似要素を h2 要素の独立した子のノードとして扱うのに対し、 Firefox や Opera は h2:first-letter 擬似要素は h2 要素と同じノードとして扱いつつも、プロパティの継承の場合は子のノードとして扱っているような感じです。

各ブラウザの擬似要素の取り扱い

......ここまで考えて気付いたのですが、 :before 擬似要素や :after 擬似要素によって生成される内容 (Generated content と呼び、 CSS2 ではhttp://www.w3.org/TR/CSS2/generate.html に、 CSS 2.1 では http://www.w3.org/TR/CSS21/generate.html にて仕様が示されています。 ) は基本的に元の要素と同じプロパティを適用するんですよね。

The :before and :after pseudo-elements inherit any inheritable properties from the element in the document tree to which they are attached.

For example, the following rules insert an open quote mark before every Q element. The color of the quote mark will be red, but the font will be the same as the font of the rest of the Q element:

q:before {
  content: open-quote;
  color: red
}

この部分は CSS2 でも CSS 2.1 でも同じ文章ですので、とりあえず CSS 2.1 の方から引用しました。 「この例ではあらゆる q 要素の前に open-quote の引用符を挿入する。 引用符の色は ( 明確に指定されているため ) 赤色になるが、色以外のフォント関連の要素は q 要素のフォント関連の要素のスタイル指定と同じになる。」 ということです。

これは、 q:before 擬似要素を単独のノードとして扱うのではなく、 q 要素のノードに含むということではないでしょうか ? もし q:before 擬似要素を単独のノードとして扱うのならば、 q 要素での指定に関わらず q:before 要素自体での指定、あるいはそれがなければユニバーサルセレクタでの指定が適用されるはずです。

http://hxxk.jp/common/css/hxxk005.css を例に考えてみましょう。

* {
    color: #000;
}

pre {
    color: #ff0;
}

という指定を pre 要素に指定しています。 ( 本当は color: #ffa; なのですが、色合いを分かりやすくするためにスクリーンショット取得の時だけ変更しています。 ) これに加え、 pre 要素でソースコードの説明で紹介したテクニックで pre[title]::before 擬似要素を追加しているのですが、これには特に color を指定しておらず、またユニバーサルセレクタにて color: #000; と指定しています。 しかし、 Firefox や Opera で表示してみれば pre 要素の color: #ff0; が pre[title]::before 擬似要素に適用されているのが分かります。 ユニバーサルセレクタの color: #f00; は適用されません。

もしかしたら、 Firefox や Opera は :first-letter 擬似要素でも同じように、 :first-letter 擬似要素にて指定が無い場合は元の要素のプロパティを適用しているのではないでしょうか ? それだと腑に落ちるのですが。 IE は 7 でも :before 擬似要素や :after 擬似要素に対応していないため、そういった流れが無く :first-letter 擬似要素は独立したノードとして扱っているのでは、と思いました。

......それだと IE 6 の表示結果の説明がうまくつきませんが、もうそこまで考えたくはありません。

3 日間のまとめ

リプライ

5 件のリプライが送られています。

2006-10-28T01:19+09:00 - itochan

仕様書などろくに見ない素人んがら、コメントします。 a:hover などは a からしっかり継承(?)してきますよね。 なにより、IE7の方法だと使い勝手が悪いです。

2006-10-28T01:40+09:00 - 186

新しい図なんですが, FirefoxやOperaってIEの方の図と同じだと思うんですが, どうでしょう. 赤線が無いだけで. 昔, contentで生成された疑似要素とtext-decorationの関係のときに調べたのですが, firefoxやoperaの方が正しい挙動だと思います.

2006-10-28T12:02+09:00 - IEは擬似要素に全称セレクタをマッチさせているように見える < 徒書

( 真琴によるトラックバック ) IEとその他のブラウザでは、擬似要素にあたる箇所に全称セレクタに対するスタイル規則を適用するかどうかについて、異なる動作...

2006-10-28T12:15+09:00 - 真琴

&#62;itochan さん IE 7 の解釈だと確かに不便ですよね。 もう *:first-letter { *: inherit; } みたいな指定をできるなら指定したいところです。プロパティにもユニバーサルプロパティとかあればいいのになあ……。

2006-10-28T12:17+09:00 - 真琴

&#62;186 さん <a href="http://hxxk.jp/2006/10/28/1200">http://hxxk.jp/2006/10/28/1200</a> にて新しい図を描いてみました。 これから出かける用事が終わったら、 186 さんが調べた記事を探してみよう……。

この記事に対するご意見やご質問、ご感想などありましたらこのフォームに簡潔に記入して下さい。 簡潔に記入できない場合や、関連記事にてご意見をお寄せいただく場合は、ご自身の weblog にて記事を書かれた上で あてにトラックバックとして送信してください。

記入フォーム

補足情報

著作、講演、制作実績など