IEのヘンテコなCSS解釈の原因と言われるhasLayoutプロパティ。
どうやらこのhasLayoutプロパティの値がfalse(デフォルト値)の場合に、いろいろとまずいことが起こるようです。IEだけfloatした要素周辺のmarginやpaddingがおかしかったり、相対配置/絶対配置した要素がどこかに消えてしまったりする・・・という経験はcssレイアウトの際に誰もがぶつかる問題です。
また、hasLayoutがTrueとFalseの要素が混在している場合には、IE7のズーム機能を利用した際に、隣あった要素が重なってしまったりします。
この辺はコリスさんのIEでのCSSのバグを回避するhasLayoutに分かりやすい説明があります。
このhasLayoutの問題を解決するためにzoomプロパティが利用されることがあります。(zoomプロパティはIEの独自拡張であるため、これを使うこと自体どうか、という意見もありますがここでは触れません)
具体的には次のように、
* {
margin: 0;
padding: 0;
zoom: 1;
}
ユニバーサルセレクタに指定したり、
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
margin:0;
padding: 0;
zoom:1;
}
などとして、ブラウザスタイルをリセットする際に同時に指定するのが一般的なようです。しかし、zoom:1;
をli要素に指定してしまうとマーカーの表示がおかしくなってしまう問題があります。
これに対しては
li {zoom: normal;}
としてzoomプロパティの値をデフォルトに戻すことで対処をできるようです。
ここまでは前提で、本題はここからです。
そんなわけで実際に業務で、スタイルリセットにzoom:1;
を導入してみたのですが、さらなる落とし穴があることに気づいてしまいました。
STOPN’ LISTENさんのclearfixに関するの記事をご覧いただくとお分かりになると思うのですが・・・そうです。zoom:1;
はclearfixにも使われるのです。
つまり、何でもかんでもzoom:1;にしてしまうと、floatが意図しないところでclearされてしまう恐れがあります。具体的には次の図のような例で、問題が起こります。
XHTMLのコード
<p><img src="/img/2007/09/16_example_img.gif" alt="画像" width="120" height="90" class="photo" /> 段落1テキスト段落1テキスト段落1テキスト段落1テキスト段落1テキスト段落1テキスト段落1テキスト段落1テキスト段落1テキスト</p>
<p>段落2テキスト段落2テキスト段落2テキスト段落2テキスト段落2テキスト段落2テキスト段落2テキスト段落2テキスト段落2テキスト</p>
最初の段落に含まれている画像に対してfloat:leftを指定し、本文を右側に回りこませているという、何の変哲もないレイアウトです。回り込んでいる本文が途中で段落分けされていることがポイントです。
ここで* {zoom: 1;}
を指定すると、以下の図のようになります。
図と同じサンプルページも用意しました(IE6/7で見てくださいね)。
段落分けされた途端、clearされてしまっているのがお分かりになるかと思います。これはp要素に対してzoom:1;
が効いているからです。これを回避するにはp {zoom:normal;}
のようにしてデフォルトの値を上書きするしかありません。個人的にこれは全くナンセンスだと思うのですが・・・。
スタイルリセットの段階でzoom:1;
を指定してしまうと、そのサイトのコンテンツは全てがこの挙動になってしまいます。
サイトをリニューアルする際にzoom:1;
を新たに導入する、という場合には注意が必要です。今まで正常に表示されていたコンテンツが、先述の例のようにレイアウトが変わってしまうことがあるからです。
サイトを一人で制作し運営していく分には、この挙動を理解した上で制作をすることになるので、全く問題はないと思います。しかし、複数人でチームを組んで一つのサイトを制作・運営する場合には状況が違います。
制作チーム全員がこの挙動を理解することが必須となるのです。人数の多いチームともなると、これはなかなかに簡単なことではありません。
よって、複数人でチームを組んで制作・運営をしている大規模サイトの制作においては、スタイルリセットにzoom:1;
を組み込むべきではない、と言えます。
ただ、やはりzoom:1;
の便利さは捨てがたいものがあります。idセレクタや子孫セレクタなどを使用して、特定の領域にだけ限定的に利用する分には問題はないでしょう。
zoom:1;
は便利ですがご利用は計画的にということです。