落とし穴。

ちょっとだけためになるかも知れないエントリ。
MSIEにはバグが多い。誰でも知ってる事実だ。IE7がリリースされてそれなりに修正されたが、いまだに結構な数のバグが健在。

ことCSSの解釈にまつわるバグは星の数ほどあり、コーディングしているとIEのみハマるなんてことは日常茶飯事、というか、コーディング作業においてかなりの時間的リソースをIEのバグとかおかしな仕様が原因で発生する問題の対処に費やしている、なんて話も結構聞くのが現実だ。

IE6時代のwidth解釈バグ(content-boxで解釈すべきところをborder-boxで解釈する)とか、あまりに致命的なものは誰もがそれを避けて書くので実はたいして大きな問題になっていなかった。

そう、問題なのはマイナーなバグなのだ。なかなか気付きにくいので普段は意識しないが、いざハマると解決が困難な、まさに「落とし穴」である。

逐次チェックしながらコーディングしていて、IEのみ表示がおかしくなる。
たとえばfloatで寄せたボックスがIEのみズレて表示されたりする。
CSSを見直してみても特に記述がおかしな点は見当たらない。
あれこれ試してみても解決せず、仕方なくGoogleで「IE float バグ」とか検索してみると「IEにはfloatさせたボックスに含まれる要素に設定したmarginの値が2倍になるバグがあります」みたいなことを書いたblogのエントリがわんさかヒットする。

とりあえずIEの表示でハマったら、それっぽい単語を並べて検索してみるといい。たいていはバグの存在とその回避方法の情報がセットで手に入る。

…が、まれにweb上でそれらしき情報が拾えない、つまりほとんど誰にも発見されていないバグに遭遇したりする。中にはびっくりするような冗談みたいなバグがあったりして、これ意図的に仕組まれてんじゃねーかと疑ってしまうようなことも。

今日はそんなバグをまたひとつ見つけちゃったよ、というお話。いちおうひととおり検索はしてみたが、それっぽい情報は得られなかった。既知の問題ならご勘弁を。

ie_hover.jpg

きっかけは某楽団のサイトで、ある人から「上部のテキストメニューが、マウスを当てると消えちゃうよ」と指摘を受けたこと。聞いて早速チェックしてみた。
当然のようにSafariやFirefoxでは再現されず、IEでのみ起こっていた。

以下は問題部分のCSS。upper-menuというidが振られたdivを絶対配置して、その中のテキストにリンクを設定してある。


#upper-menu {
color: #fff;
font-family: "ヒラギノ丸ゴ Pro W4", "Hiragino Maru Gothic Pro";
font-size: 10px;
line-height: 1;
text-align: right;
position: absolute;
top: 75px;
left: 163px;
width: 468px;
height: 15px;
}

#upper-menu a:link {
color: #fff;
}
#upper-menu a:hover {
background-color: #fff;
color: #093;
}

この#093という色は親ボックスの背景色と同じ。つまり背景色とhover時の文字色が同じだったので、hover時のbackgroundが適応されずに「文字が消えた」というわけだ。

これはアクセシビリティ的にもちょっと問題がある(つまり、仮に疑似要素:hoverのbackgroundプロパティを無視するようなブラウザがあった場合、同じ事が起こる)ので、hover時の文字色を変更してとりあえずは解決したが、IEで意図したとおりに表示されないというのはなんとも気持ち悪いので根本的な解決手段を探すことに。

まず疑ったのは親要素にあるposition: absolute。絶対配置と背景にまつわるバグには過去何度も遭遇していたからだ。position: absoluteと配置に関わるすべてのプロパティを無効にしてみてチェックしてみた。が、解決せず。というか、親要素にある全てのプロパティをコメントアウトしてみても問題が再現していた。

これは迷宮入りかと思われたが、ふとhtmlファイルのほうでupper-menuが振られたdivの位置を変えてみたところ、ウソのようにあっさりと解決した。具体的には、headerというdivの中から出してみた。

header内には画像で構成したメニューがあったので、display: blockをかけたa要素のために、#header内のすべてのa要素に対してborder: 0を指定していた。つまり、問題のリンク部分にもborder: 0が適応されていたことになる。

どうやらそのborder: 0がひとつの引き金になっているようだ。

いろいろ実験してみた。ソースを参照のうえ、IE7で見て欲しい。上から二つめが問題の現象。なお、他のブラウザ(6以前のIEも含む)では問題は再現されない。

まとめるとこうである。

a要素のborderが0に設定されていて、なおかつ疑似要素:hoverのbackgroundに白(#fffとか#ffffffとか)が設定されている場合、マウスオーバー時にa要素の背景が消える

ちなみに、「白」を「透明」として解釈しているだけのようで、例えば#effとかなら普通に適応される。また、直近の親要素に対してbackgroundが指定されていると発生しない。値がtransparentでも問題ないので、手っ取り早く解決したい場合はひとつ外側のボックスにbackground: transparentを書いてやればよい。

a要素にborder: 0を指定することはたぶんあんまりないが、今回のように別のところに指定していたはずがついうっかり巻き込まれていた、ということはあり得る。これに限らずCSSの継承関係には気を払うべきだろう。

それにしても、なんとも理解しがたいバグである。非常に限定的な状況でしか再現しない分、ハマるとやっかいそうである。ていうか、なんで白を透明と解釈する必要があるのか…。

ちなみにこれはWindowsXP上のIE7で発生。IE6では再現しなかったので、IE7で追加(?)されたもののようです。恐るべしMicrosoft。

カテゴリ:Web | - | trackbacks (0)

<< 春眠暁を覚えず。 | スイカ2008。 >>

Trackbacks