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では次のように期待通り表示されます。
2.問題点
冒頭の画像と同じですが、Google Chrome(9.0.597.107)では次のようにレイアウトが崩れます。
form要素にfieldset要素を挿入しても事象は変わりません。
3.事象の詳細
レイアウト崩れは、以下の条件を満たしたときに発生することを確認しています。
- 文字エンコーディングがEUC-JP
- 全称セレクタにmargin/padding/font-familyを設定
- dt要素セレクタにpaddingを設定(topまたはbottomに0以外を同時に指定)
- 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での解消後の表示は次のようになります。
ちなみに、この事象が発生したのは文字エンコーディングがEUCのFC2ブログです。本問題について認識誤り(clearfixはそもそも必要など)等ありましたらご指摘頂ければ幸いです。
- YouTube動画にキャプションをつけてテキストを回り込ませる方法
- 画像を下揃えにしてテキストを回り込ませる方法
- style要素にCSSの擬似要素は記述可能か?
- position:relativeを設定すると他の要素がずれる場合の対処
- CSSでタブ切り替えする方法
- :target擬似クラスのまとめ
- CSSでヘッダを固定したスクロールテーブルを作る方法
- レスポンシブウェブデザインで画像を縮小する方法
- disabledなボタンのhoverのスタイルを無効にする方法
- HTML要素を別の要素を基点にしてCSSで絶対配置する方法
- :not擬似クラスでCSS3のサポートをチェックする方法
- :checked擬似クラスでチェックボックスに連動して要素を表示させる方法
- ol要素の入れ子で親の番号を子に割り当てる方法
- チェックボックスやラジオボタンを大きくする方法
- CSSで中央に配置する方法
詳しく調べていないのですが、
おそらく、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などを使用したほうが良さそうです。
>lowplyさん
こんばんは。
詳細な解説とCSSのご提示、ありがとうございました。
大変勉強になりました!
精進致します。
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にした方が、文法的には正しいのではないかと思います。
>たかはしさん
こんばんは。
アドバイスありがとうございました!
色々試してみたいと思います。
まずはお礼まで。