2009年8月28日金曜日

Firefox 3.5 の display: table;(table-row; table-cell;) 関連の挙動について

※この記事は古いバージョンの Firefox について書いた内容です。最新バージョンでは正常に動作しています。

Firefox 3.5 の CSS のレンダリングには仕様なのかバグなのかよくわからない挙動が起きることがあります。

というか恐らくバグなのですが、簡単にいえば、CSSで display: table-cell; を指定してマルチカラムレイアウトを行っている場合に Firefox 3.5 だとまれにカラム落ちしてしまうという現象が起きてしまいます。

現象

まず以下のサンプルを見ていただきたいと思います。

新しいウィンドウで開く

Firefox 3.5 で見たときどのように表示されていたでしょうか?

ソースは以下のようになっています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>テスト</title>
<style type="text/css"> 
#main {
	display: table;
	table-layout: fixed;
	width: 400px;
}
#left {
	display: table-cell;
	width: 200px;
	background-color: aqua;
	overflow: hidden;
} 
#right {
	display: table-cell;
	width: 200px;
	background-color: orange;
}
</style>
<body>
<div id="main"> 
<div id="left">
<p>200px</p>
<input type="button" value="ボタン" onclick="aaa()" />
<script type="text/javascript"> 
function aaa() {
	alert("Hello World.");
}
</script>
</div>
<div id="right">200px</div>
</div>
</body>
</html>

CSS で ブロック要素をテーブルに見立てる場合は親のボックス、このソースの場合は #main に対し、display: table; を指定します。

次に、#main の子要素には display: table-cell; を指定するすると以下の図のような表示になるはずです。(IE8 による正しい表示)

default

そして Firefox では以下の図のように表示されていたと思います。ただし、これは必ずではなく正しく表示される場合と誤って表示される場合があります。

mistake

ここで、HTML に詳しい方はすでに以下のことに気づいているかもしれしません。

  • display: table; = <table>
  • display: table-row = <tr>
  • display: table-cell; = <td>

だとするなら、上記のソースでは <tr> に該当する指定がどこにも見当たらないということに。

しかし、CSS の仕様では table-cell,HTMLでいう<td> の直接の親要素(この場合は table-row, HTMLでいう <tr>)にあたるモノが存在しない場合、レンダリングエンジンはそれらの要素の前後に必要な要素を追加しレンダリングすることになっています。

これは、レンダリングエンジンがその要素をあるものとして仮定しレンダリングをするので、DOM上では追加されていないままになっています。

つまり、Firefoxではパースを行いレンダリングする際に、何らかの不備があり、まれに<tr>要素の追加をできないまま、横並びにならずカラム落ちしてしまうことになります。

注意

ただ、どんな環境でも等しくカラム落ちするというわけではありません。ローカルでプレビューした場合は特に問題なく表示されていることでしょう。

上記のHTMLの場合はおそらく忍者のサーバーに置いていることに原因があります。このサーバーは HTML に広告を追加するような設定になっていますが、その際に<tr>の追加に悪い影響を与えているのではないかと思います。

広告が追加されないサーバーでも F5 キーを押して何度も再読み込みをすればカラム落ちすることがあります。

解決方法

<tr> の生成に不具合があることは次のようにソースを修正することによって予測できます。

#main {
	display: table;
	display: table-row;
}

これでプレビューしてみましょう。すると、Firefoxで何度ページを読み直してもカラム落ちしないようになっているはずです。

新しいウィンドウで開く

これで、原因はおそらく上記のように <tr> の生成に問題があったということが証明できそうです。

<table>に該当する要素がありませんが・・・ と、思った人もいるでしょうが、この場合も<tr>の前後には<table>があるものとしてレンダリングが行われています。

同じように<table>の生成に不具合があったとしても、この場合は<tr>と<td>の関係によって見た目上は正しく表示できているのでしょう。

最後に

どうでしょうか、これは Firefox のバグだと思いますか?もしバグだとするなら Firefox も完璧ではないということになりそうです。

そして逆に IE8 が(少なくともこの点に関しては)しっかり作られていると言えそうです。