Tutorial
この記事の読了時間:約10分9秒
CSSコーディングにおいて最も忌むべきもの、それはIE6。
「ホントに仕様書読んで作ったのか?」と疑いたくなるほどのオリジナリティ溢れるCSS解釈は、IE6の絶大なシェアとも相まって、一層容赦ない問題となりました。
世には様々なハック術や回避方法が出回るも、それ自体がIE6のバグを利用したモノだったりして、IE立てればOpera立たず、みたいな状況に脳ミソとろけた経験のある方も多いのではないでしょーか。
今回のエントリーでは、そんなIE6で頻出するCSSバグと、それを対処 / 回避するハック術なんかを取り上げてみたいと思います。
これでもうIE6なんざ怖くない!?
恐らく最も引っかかるであろう、この凶悪なバグ。
このバグに見舞われてしまう条件はものすごくカンタンで、「floatさせた要素に、floatした方向と同じ方向へmarginを設定する」ってだけ。
例えばあるdivをfloat:leftしたとして、そのdivにmargin-left:10pxって指定すると、なぜかIE6では左方向のmarginが20px分になってしまいます。
「どうしてこうなった!?」と、某AAを思い浮かべてしまうほどの酷い仕様ですが、これは案外サラっと直せます。
これらのどの方法でもmarginの挙動は通常通りとなります。状況に合わせてお好きなものをお使い下さい☆
ちなみに、IE6にだけ効くIEハックの方法は以前「(恐らく)最も簡単な、対IE用CSSハック術」というエントリーでも書きましたが、こんな感じかと。
div { margin-left:10px; _margin-left:5px; }
marginプロパティの前にアンダーバーを入れると、IE6以外のブラウザはアンダーバー以降の記述を無視するので、結果的にIE6だけ反映されるという具合です。
要素の最大 / 最小幅を指定する「min-width / max-width」ですが、IE6はコチラに対応していません。
「ウィンドウの幅に合わせてサイズが可変するdiv」なんかを実現させる際にも便利なこれらのプロパティですが、IE6でもやりようによっては再現できちゃいます。
まず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な挙動を得られますよ!
横並びメニューやパンくずリストなんかには最適最強のプロパティ「inline-block」ですが、これに対してもIE6は実にユニークかつ大胆な仕様を持っていて、ボックス要素に対してのinline-block指定は華麗に無視してくれます。
しかしながら、これは逆にIE独自のプロパティ「zoom」を利用するコトで、みごと良い感じの挙動になります。
div { display:inline-block; _display:inline; _zoom:1; }
この「zoom」とは、「画像や文字の拡大率 / 縮小率」を指定するIE独自のプロパティですが、このプロパティを設定すると副産物として、IEのレンダリングバグの元凶「hasLayout」という読み取り専用プロパティの値を、「false」から「true」へと変えてくれます。
そもそも画像や文字は本来「見て欲しい大きさ」で表示させてるはずで、わざわざ拡大縮小率とか指定する必要性にも乏しいとのコトで、もはやhasLayout専用プロパティと化してるzoom萌え。
画面をスクロールすると突然表示されたり、リンクに触ろうとするとフワっと消えたり。
そういう場合、まずこのピーカブーバグってのを疑ってみてください。
このバグはfloatに内包されたコンテンツ、またはfloat要素に接する背景やborderなどが表示されたりされなかったり、っていうもの。
まるで「いないいないばぁ = peek-a-boo」ってコトで、ピーカブーバグと呼ばれています。まぁカワイイ。
結構良く出現するバグかと思いますが、これもサラっと解決する方法があります。
これまた出てきたzoom:1ですが、今回もコレが一番良さそうな対処法かなと。
それではここからオマケとして、ワタクシ的に意識してるコーディング方法というか、IEを念頭に置いたCSSコーディングのコツみたいなものをさらけ出してみようかと思います。
大したコトでは無いですが、気にしとくと後々ラクできるので良いですよー。
IE6はHTMLソースの一行目にDOCTYPE宣言が記述されていないと、自動的に後方互換モード(IE6より前のバージョンと同じようにCSSを解釈)になってしまいます。
「一行目にDOCTYPE宣言」は絶対の条件らしく、例えばXHTMLの正式仕様では1行目にXML宣言を記述するべきなのですが、ソレやっちゃうと後方互換モードになり、バグの素となります。
なので、XHTMLの場合でも1行目のXML宣言はせず、DOCTYPE宣言から書き始めるようにして、何が何でも標準準拠モードにするようにします。
これは大手企業サイトでも一般的に使われている手法ですね。
margin2倍バグやピーカブーバグをはじめ、float周りはバグが潜む可能性の高い部分です。
borderをボックス内に含むか含まないかとかの細かな部分が、鬼のカラム落ちを引き起こしたりもするので、意識しつつとにかく目視!
あとは可能であれば、あまりカッチリとしたレイアウトにしないで、floatしたもの同士の隙間を柔軟に持てるようにしちゃったり。
でもとにかく目視!コレ最強!
何かおかしーなーって時は、大概の場合は前述のhasLayoutプロパティが原因だったりします。
なので、困ったらまずはその要素にzoom:1を当ててみます。
それで直ればそれで良し、もしも直らなかったら、その要素自体がIE6に対応してないとかって可能性から考えていきましょう。
7割がた、アナタよりIE6の方が間違ってますからw
ただ、この破天荒な仕様が需要を生んだのも事実。
足を向けては寝れないけど、隣で眠ってたら寝ぼけたフリしてエルボー入れたい、みたいな。
。。。違うか。
関連する記事
同じカテゴリーの記事
smkn より:
2011/07/09 11:27 PM
>nironin 様
うはー!ありがとーございますっ!
こちらこそ今後も頑張っていきますので、なにとぞよろしくです♪
nironin より:
2011/07/08 8:32 PM
いつも参考にさせて頂いています。
何か調べるといつもここで解決します。
わかりやすく解説していただいて大変助かります。
今後も宜しくお願いします。