Google Chromeでfloatレイアウトが崩れる件について

Google Chromeでfloatレイアウトが崩れる件について

Posted at March 2,2011 1:55 AM
Tag:[CSS, GoogleChrome, TroubleShooting]

Google Chromeでfloatレイアウトが崩れる事象が発生しました。

Google Chromeでfloatレイアウトが崩れる事象

かなりレアケースと思われますが、備忘録として以下に詳細を残しておきます。

1.サンプル

サンプルはdl/dt/dd要素を使ったfloatレイアウトで、コメントフォームを想定しています。

(X)HTML(赤色が対象部分)

<?xml version="1.0" encoding="euc-jp"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<link rel="stylesheet" href="style.css" type="text/css" />
<title>test</title>
</head>
<body>
<div>
  <form method="post" action="hoge.cgi" name="comment_form" id="comment_form">
    <dl>
       <dt>名前:</dt>
       <dd><input id="author" name="author" size="20" value="" /></dd>
       <dt>メールアドレス:</dt>
       <dd><input id="email" name="email" size="30" value="" /></dd>
       <dt>URL:</dt>
       <dd><input id="url" name="url" size="30" value="" /></dd>
       <dt>コメント:</dt>
       <dd><textarea id="comment" name="comment" rows="5" cols="30">Please comment.</textarea></dd>
    </dl>
  </form>
</div>
</body>
</html>

CSS(すべて対象)

* {
    margin: 0;
    padding: 0;
    font-family: Verdana, Arial, sans-serif;
}
dl {
    margin: 10px;
}
dt {
    float: left;
    width: 120px;
    padding: 5px 5px 5px 0;
    text-align: right;
}
dd {
    padding: 5px 0 5px 8px;
}
input,textarea {
    font-family: "Osaka", "ヒラギノ角ゴ Pro W3", "MS Pゴシック", arial, sans-serif;
}

このサンプルは、Firefox 3.6.13では次のように期待通り表示されます。

Firefoxでの表示

2.問題点

冒頭の画像と同じですが、Google Chrome(9.0.597.107)では次のようにレイアウトが崩れます。

Google Chromeでの表示

form要素にfieldset要素を挿入しても事象は変わりません。

3.事象の詳細

レイアウト崩れは、以下の条件を満たしたときに発生することを確認しています。

  1. 文字エンコーディングがEUC-JP
  2. 全称セレクタにmargin/padding/font-familyを設定
  3. dt要素セレクタにpaddingを設定(topまたはbottomに0以外を同時に指定)
  4. input要素セレクタにfont-family、値に「MS Pゴシック」を設定

例えば次の条件であればこの事象は発生しません。

  • 文字エンコーディングがUTF-8である場合
  • 全称セレクタにあるmargin/padding/font-familyのいずれかひとつでも欠けている場合
  • dt要素セレクタのpadding-topまたはpadding-bottomのいずれかが0を設定、または設定されていない場合

4.対処

3項の1~4の条件をひとつでもはずせば問題は解消します。3項の条件を満たす必要がある場合でも、dd要素にいわゆるclearfixを設定すれば問題は解消されるようです。

(X)HTML

…前略…
<div>
  <form method="post" action="hoge.cgi" name="comment_form" id="comment_form">
    <dl>
       <dt>名前:</dt>
       <dd class="clearfix"><input id="author" name="author" size="20" value="" /></dd>
       <dt>メールアドレス:</dt>
       <dd class="clearfix"><input id="email" name="email" size="30" value="" /></dd>
       <dt>URL:</dt>
       <dd class="clearfix"><input id="url" name="url" size="30" value="" /></dd>
       <dt>コメント:</dt>
       <dd class="clearfix"><textarea id="comment" name="comment" rows="5" cols="30">Please comment.</textarea></dd>
    </dl>
  </form>
</div>
…後略…

CSS

…前略…
.clearfix:after {
    content: "";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {display: inline-table;}
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */

Google Chromeでの解消後の表示は次のようになります。

Chromeでの解消後の表示

ちなみに、この事象が発生したのは文字エンコーディングがEUCのFC2ブログです。本問題について認識誤り(clearfixはそもそも必要など)等ありましたらご指摘頂ければ幸いです。

関連記事
zenback
人気エントリー
トラックバックURL


コメント

詳しく調べていないのですが、
おそらく、FirefoxよりChrome(WebKit)の方が正確なレンダリングをするはずなので
HTMLの解釈としては間違っていないように思います。

また、文字コードや全称セレクタは今回は関係なさそうですが(すみません検証していません)
dtの上下paddingが原因でdt同士がぶつかってfloatしきれていない感じですね。
ご指摘のとおりdtのpaddingを0にすれば解消しました。

検証するためにdtとddに背景色をつけてみると分かりやすいと思いますが、
floatしているdtの下にddが入り込み、幅指定もされていないので
ddが画面いっぱいに下敷きのように広がってしまい、あまり美しくないです。

dl dt ddでこういったレイアウトをしたい場合
・dtに幅指定をして左float
だけではなく、
・ddにも幅指定をして左float(幅指定は必須ではないがfloatする場合は指定したほうが無難)
・dtで左clear
とすると期待されているレイアウトを美しく再現できます。

またdl内のすべての要素がfloatしているので
dl自体にoverflow hiddenを指定して高さを確保します。
というわけでこんなCSSで行けるかと思います。

/* ------------------------------- */

* {
margin: 0;
padding: 0;
font-family: Verdana, Arial, sans-serif;
}
dl {
margin: 10px;
overflow:hidden; /* 追加 */
}
dt {
float: left;
clear:left;
width: 120px;
padding: 5px 5px 5px 0;
text-align: right;
background:red;
}

dd {
width:300px; /* 追加 */
float:left; /* 追加 */
padding: 5px 0 5px 8px;
background:aqua;
}
input,textarea {
font-family: "Osaka", "ヒラギノ角ゴ Pro W3", "MS Pゴシック", arial, sans-serif;
}

/* ------------------------------- */


# clearfixは本来の目的ではない部分でafter擬似要素を使ったり
特定のブラウザ向けに特殊な指定をしたりしているので、
できれば使わないほうが良さそうです。

# 全称セレクタも出来ればreset.cssなどを使用したほうが良さそうです。

[1] Posted by lowply : March 2, 2011 11:23 PM

>lowplyさん
こんばんは。
詳細な解説とCSSのご提示、ありがとうございました。
大変勉強になりました!
精進致します。

[2] Posted by yujiro logo : March 3, 2011 1:21 AM

dtとddの高さを揃えれば、なおらないでしょうか?

dtには文字が入っていて、ddには文字がなくinput要素だけなので、それぞれの高さが変わって(今回の場合はddよりdtの高さが高くなっている)しまっているのではと思います。

(ブラウザによってはスタイルシートの”/* フォーム */”というところに設定してあるinputのfont-sizeも影響してくる?)

1.dtとddにheight: 1.5emなどを設定して高さを揃える。
2.dtの中にある「:」をddに入れて高さが揃う様にする。

などが考えられそうですが、以下のような問題もあります。
1の場合はデフォルトのフォントサイズが大きくてdtの中で改行が発生してしまうとdtの中身が重なってしまう。
2の場合はマークアップ的に「:」の位置がおかしい。

ところで、コメント欄のHTMLでlabel要素がdisplay:blockになっていますが、dt要素はインライン要素とテキストしか含むことができない様です。なので、dt要素もdisplay:blockにした方が、文法的には正しいのではないかと思います。

[3] Posted by たかはし : March 3, 2011 6:31 AM

>たかはしさん
こんばんは。
アドバイスありがとうございました!
色々試してみたいと思います。

まずはお礼まで。

[4] Posted by yujiro logo : March 4, 2011 2:57 AM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)