Own products

Tutorial

2009
10/28

IE6の頻出CSSバグいろいろと、それに対処するハック術

この記事の読了時間:約109

  • このエントリーをはてなブックマークに追加

CSSコーディングにおいて最も忌むべきもの、それはIE6

「ホントに仕様書読んで作ったのか?」と疑いたくなるほどのオリジナリティ溢れるCSS解釈は、IE6の絶大なシェアとも相まって、一層容赦ない問題となりました。

世には様々なハック術や回避方法が出回るも、それ自体がIE6のバグを利用したモノだったりして、IE立てればOpera立たず、みたいな状況に脳ミソとろけた経験のある方も多いのではないでしょーか。

今回のエントリーでは、そんなIE6で頻出するCSSバグと、それを対処 / 回避するハック術なんかを取り上げてみたいと思います。

これでもうIE6なんざ怖くない!?

IE6の頻出CSSバグと対処ハック術

1.横方向のmarginが倍になっちゃうバグ。

恐らく最も引っかかるであろう、この凶悪なバグ。

このバグに見舞われてしまう条件はものすごくカンタンで、「floatさせた要素に、floatした方向と同じ方向へmarginを設定する」ってだけ。

例えばあるdivをfloat:leftしたとして、そのdivにmargin-left:10pxって指定すると、なぜかIE6では左方向のmarginが20px分になってしまいます。

「どうしてこうなった!?」と、某AAを思い浮かべてしまうほどの酷い仕様ですが、これは案外サラっと直せます。

横方向のmarginが倍になっちゃうバグの対処法:

  1. 該当要素に「display:inline」を追記する。
  2. 「margin」の代わりに「padding」を使用する。
  3. IEハックを使ってIE6にだけ「margin」の値を半分に指定する。

これらのどの方法でもmarginの挙動は通常通りとなります。状況に合わせてお好きなものをお使い下さい☆

ちなみに、IE6にだけ効くIEハックの方法は以前「(恐らく)最も簡単な、対IE用CSSハック術」というエントリーでも書きましたが、こんな感じかと。

div {
	margin-left:10px;
	_margin-left:5px;
}

marginプロパティの前にアンダーバーを入れると、IE6以外のブラウザはアンダーバー以降の記述を無視するので、結果的にIE6だけ反映されるという具合です。

参考サイト

2.min-width、max-widthに対応してない。

要素の最大 / 最小幅を指定する「min-width / max-width」ですが、IE6はコチラに対応していません。

「ウィンドウの幅に合わせてサイズが可変するdiv」なんかを実現させる際にも便利なこれらのプロパティですが、IE6でもやりようによっては再現できちゃいます。

min-width / max-widthのIE6対処法:

  1. 専用JavaScriptライブラリ「minmax.js」を使う。
  2. IE独自のプロパティ「expression」を使う。
  3. ページにJavaScriptを直書きする。

まず1番目の『専用JavaScriptライブラリ「minmax.js」』ですが、一番カンタンっちゃーカンタンですが、ウワサによるとdiv以外の要素に適応させると挙動がおかしいという情報もあったり。

で、2番目の『IE独自のプロパティ「expression」』ですが、CSSの不調はCSSで対応するという意味では、一番しっくりくる対処法のような気がします。

div {
	min-width:200px;
	max-width:650px;
	width:expression(document.body.clientWidth < 202? "200px" : document.body.clientWidth > 650? "650px" : "auto");
}

「expression」とは、CSS内でJavaScriptが使えるというIE独自仕様なんですが、コレはコレでちょっと問題があって、状況や環境によってですが、ものっくそ重い場合があります。

また、たまに見かけるmin-widthの対処法として下記のようなモノがあります。

div {
	min-width: 200px;
	width: auto !important;
	width: 200px;
}

ですがコレ色々ハック使ってますが、IE側の視点で見ると単純にwidth:200pxしてるってだけです(そもそも対応してないmin-width + 「同一枠内での!important指定は無視される」というIE6のバグ)。

とやかく言いましたが、個人的には3番目の「ページにJavaScriptを直書きする」ってゆーのがオススメです。

<script type="text/javascript">
(function(){
	if(navigator.userAgent.indexOf("MSIE 6.0")==-1) return;
	var min_max_width = function(){
		var w = document.body.clientWidth;
	document.getElementById("対応させたい要素のID名").style.width = w < 602? "600px" : w > 900? "900px" : "auto";
	};

	attachEvent("onload" , min_max_width);
	attachEvent("onresize", min_max_width);
})();
</script>

こんな感じでページ内に書いておけば、対応させたい要素名に当該スクリプトが反応し、あたかもmin-width / max-widthな挙動を得られますよ!

参考サイト

3.ブロック要素にinline-blockが効かない。

横並びメニューやパンくずリストなんかには最適最強のプロパティ「inline-block」ですが、これに対してもIE6は実にユニークかつ大胆な仕様を持っていて、ボックス要素に対してのinline-block指定は華麗に無視してくれます。

しかしながら、これは逆にIE独自のプロパティ「zoom」を利用するコトで、みごと良い感じの挙動になります。

div {
	display:inline-block;
	_display:inline;
	_zoom:1;
}

この「zoom」とは、「画像や文字の拡大率 / 縮小率」を指定するIE独自のプロパティですが、このプロパティを設定すると副産物として、IEのレンダリングバグの元凶「hasLayout」という読み取り専用プロパティの値を、「false」から「true」へと変えてくれます。

そもそも画像や文字は本来「見て欲しい大きさ」で表示させてるはずで、わざわざ拡大縮小率とか指定する必要性にも乏しいとのコトで、もはやhasLayout専用プロパティと化してるzoom萌え。

参考サイト

4.リンクや文字や背景やborderが表示されたりされなかったり( = ピーカブーバグ)。

画面をスクロールすると突然表示されたり、リンクに触ろうとするとフワっと消えたり。

そういう場合、まずこのピーカブーバグってのを疑ってみてください。

このバグはfloatに内包されたコンテンツ、またはfloat要素に接する背景やborderなどが表示されたりされなかったり、っていうもの。

まるで「いないいないばぁ = peek-a-boo」ってコトで、ピーカブーバグと呼ばれています。まぁカワイイ。

結構良く出現するバグかと思いますが、これもサラっと解決する方法があります。

ピーカブーバグの対処法:

  1. floatの親要素にline-heightを指定する。
  2. floatの親要素にwidthまたはheightを指定する。
  3. バグる要素にposition:relativeを指定する。
  4. バグる要素にzoom:1を指定する。

これまた出てきたzoom:1ですが、今回もコレが一番良さそうな対処法かなと。

参考サイト

IE6を考慮したコーディングのコツ

それではここからオマケとして、ワタクシ的に意識してるコーディング方法というか、IEを念頭に置いたCSSコーディングのコツみたいなものをさらけ出してみようかと思います。

大したコトでは無いですが、気にしとくと後々ラクできるので良いですよー。

文頭のXML宣言や、DOCTYPE宣言に気をつける

IE6はHTMLソースの一行目にDOCTYPE宣言が記述されていないと、自動的に後方互換モード(IE6より前のバージョンと同じようにCSSを解釈)になってしまいます。

「一行目にDOCTYPE宣言」は絶対の条件らしく、例えばXHTMLの正式仕様では1行目にXML宣言を記述するべきなのですが、ソレやっちゃうと後方互換モードになり、バグの素となります。

なので、XHTMLの場合でも1行目のXML宣言はせず、DOCTYPE宣言から書き始めるようにして、何が何でも標準準拠モードにするようにします。

これは大手企業サイトでも一般的に使われている手法ですね。

float周りはキケンがいっぱい。

margin2倍バグやピーカブーバグをはじめ、float周りはバグが潜む可能性の高い部分です。

borderをボックス内に含むか含まないかとかの細かな部分が、鬼のカラム落ちを引き起こしたりもするので、意識しつつとにかく目視!

あとは可能であれば、あまりカッチリとしたレイアウトにしないで、floatしたもの同士の隙間を柔軟に持てるようにしちゃったり。

でもとにかく目視!コレ最強!

困ったらzoom:1。

何かおかしーなーって時は、大概の場合は前述のhasLayoutプロパティが原因だったりします。

なので、困ったらまずはその要素にzoom:1を当ててみます。

それで直ればそれで良し、もしも直らなかったら、その要素自体がIE6に対応してないとかって可能性から考えていきましょう。

7割がた、アナタよりIE6の方が間違ってますからw

MSも7とか言う前にやるコトあるだろと問い詰めたい。小一時間以上問い詰めたい。

ただ、この破天荒な仕様が需要を生んだのも事実。

足を向けては寝れないけど、隣で眠ってたら寝ぼけたフリしてエルボー入れたい、みたいな。

。。。違うか。

  • このエントリーをはてなブックマークに追加

コメント一覧

4 Responses to [IE6の頻出CSSバグいろいろと、それに対処するハック術]

[...] 【参考】 IE6の頻出CSSバグいろいろと、それに対処するハック術 Category: 未分類 [...]

[...] 【参考】 IE6の頻出CSSバグいろいろと、それに対処するハック術 Published: 11月 6th, 2010 at 1:56 Categories: css, IE ← 遭遇IE6バグ - スクロールバーが出る今回のIE対応まとめ → [...]

nironin より:

2011/07/08 8:32 PM

いつも参考にさせて頂いています。
何か調べるといつもここで解決します。
わかりやすく解説していただいて大変助かります。
今後も宜しくお願いします。

smkn より:

2011/07/09 11:27 PM

>nironin 様
うはー!ありがとーございますっ!
こちらこそ今後も頑張っていきますので、なにとぞよろしくです♪

  • このブログのRSSを購読する
  • このブログをtwitterでつぶやく
  • このブログをFacebookで共有する
  • このブログをはてなブックマークで共有する

Favorite feeds

    Contact

    お名前※必須

    ご連絡先メールアドレス

    お問い合わせ内容※必須

    CAPTCHA

    captcha

    Blog parts

    Affiliate