IE6対応(クロスブラウザ対応)というのはこんなに大変だったんだよ、というサンプルです。
元記事はこちらです。(※数年後に読んでも違和感のないように、すべて過去形でお送りします:-)
IE6で見ると両端のマージンが共に20pxになっていたでしょう。
<div id="contents" class="clearfix"> <div class="floarL">左へfloatする要素</div> <div class="floarR">右へfloatする要素</div> </div>
.floatL, .floatR {
width: 200px;
margin: 10px;
color: white;
}
.floatL {
float: left;
background: blue;
}
.floatR {
float: right;
background: red;
}
これを解決するには、floatしている要素にdisplay: inline;を指定する方法がありました。
もしくはfloatした方向にはmarginを指定しないという方法がありました。
<div id="contents" class="clearfix"> <div class="floarL">左へfloatする要素</div> <div class="floarR">右へfloatする要素</div> </div>
.floatL, .floatR {
width: 200px;
margin: 10px;
color: white;
display: inline;
}
.floatL {
float: left;
background: blue;
}
.floatR {
float: right;
background: red;
}
後方互換モードのIE6で見ると、両ボックスの高さ・幅は、ともに200pxになっていたでしょう。
<div id="contents" class="clearfix"> <div class="floarL">パディングした要素</div> <div class="floarR">ボーダーした要素</div> </div>
.floatL, .floatR {
width: 200px;
height: 200px;
}
.floatL {
padding: 10px;
}
.floatR {
border: 10px #ccc solid;
}
これを解決するには、「スターハック」というIE6のみでしか認識しない書き方で、padding/border分を足したwidth指定を追加し、IE6のみwidthを上書きする方法がありました。
もしくは、width/heightとpadding/borderは一緒に指定しないという方法がありました。
<div id="contents" class="clearfix"> <div class="floarL">パディングした要素</div> <div class="floarR">ボーダーした要素</div> </div>
.floatL, .floatR {
width: 200px;
height: 200px;
}
* html .floatL,
* html .floatR {
width: 220px;
height: 220px;
}
.floatL {
padding: 10px;
}
.floatR {
border: 10px #ccc solid;
}
floatしている要素の中身を、さらにdiv要素で囲い、外の要素にpadding/borderを、中の要素にwidth/heightを指定しました。
もう、どれが正しいのか分からなくなってますが、上と同じ結果(高さ・幅ともに220px)になったのはMac Safari 5.1.2、Mac Chrome 16.0.9、標準準拠モード時のIE(全パージョン)。後方互換モード時のIE6では、幅のみ220pxで、高さは200pxとなり惜しい結果でした。
Mac Firefox 9.0.1、Opera 11.6ではともに、paddingの方は高さ200px、幅220px、borderの方は高さ210px、幅220pxという結果に…。
IE、テーブルには強いです!
<div class="contents clearfix"> <div class="floatL"> <table summary="width/heightとpaddingを同時に指定した時に起こるバグのテスト"> <tr> <td>パディングしたtd要素</td> </tr> </table> </div> <div class="floatR"> <table summary="width/heightとborderを同時に指定した時に起こるバグのテスト"> <tr> <td>ボーダーしたtd要素</td> </tr> </table> </div> </div>
#table-padding table td {
width: 200px;
height: 200px;
}
#table-padding .floatL table td {
padding: 10px;
}
#table-padding .floatR table td {
border: 10px #ccc solid;
}
| パディングしたtd要素 |
| ボーダーしたtd要素 |
table内でも、「width/heightとpadding/borderを一緒に指定しないで解決した」ものと同じ要領で、td要素の中にdiv要素を入れ、td要素にpadding/borderを、中のdiv要素にwidth/heightをと、width/heightとpadding/borderを分けてみると、さすがにすべて同じ結果(高さ・幅ともに220px)になりました。
<div class="contents clearfix"> <div class="floatL"> <table summary="width/heightとpaddingを同時に指定した時に起こるバグのテスト"> <tr> <td><div>パディングしたdiv要素を入れたtd要素</div></td> </tr> </table> </div> <div class="floatR"> <table summary="width/heightとborderを同時に指定した時に起こるバグのテスト"> <tr> <td><div>ボーダーしたdiv要素を入れたtd要素</div></td> </tr> </table> </div> </div>
#table-padding table td div {
width: 200px;
height: 200px;
}
#table-padding .floatL table td {
padding: 10px;
}
#table-padding .floatR table td {
border: 10px #ccc solid;
}
パディングしたdiv要素を入れたtd要素 |
ボーダーしたdiv要素を入れたtd要素 |
IE6で見ると、青いボックスの上部が20px分、途切れてしまったでしょう。
これは、マイナスマージンとともにposition: relative;を指定する事で解決できました。
<div id="contents" class="clearfix"> <div class="floatL">上マージンにマイナス値を指定した要素</div> <div class="floatR">上マージンにマイナス値を指定した要素</div> </div>
.floatL, .floatR {
width: 200px;
height: 200px;
margin-top: -20px;
}
.floatL {
background-color: red;
}
.floatR {
position: relative;
background-color: blue;
}
IE6で見ると、青いボックスのみ縦長に表示されたでしょう。
これは、width/heightの指定とともにfont-size: 0;を指定する事で解決できました。
IE6でフォントサイズを大きくまたは小さくしても、青枠内のフォントサイズは変わらなかったでしょう。
<div id="contents" class="clearfix"> <div class="floatL"><p>フォントを「px」で指定した要素</p></div> <div class="floatR"><p>フォントを「%」で指定した要素</p></div> </div>
.floatL {
border: 10px blue solid;
font-size: 12px;
}
.floatR {
border: 10px red solid;
font-size: 75%;
}
フォントサイズを「12px」に指定した要素
フォントサイズを「75%」に指定した要素
borderにtransparentを指定すると、その要素のcolorで指定している色でborderが表示されてしまいました。下のサンプルの右側はborderを諦めてpaddingで対応したサンプルです。
ロールオーバーしたときに枠の色を変えたい場合は、a要素の中身をspanで囲い、a要素の背景色でロールオーバー後の枠の色を表示させました。(これは今でも使うかな?)
<div id="contents" class="clearfix"> <div class="floatL"><a href="">透明のボーダーを指定した要素</a></div> <div class="floatR"><a href=""><span>ボーダーを諦めてパディングにした要素</span></a></div> </div>
a, a span {
display: block;
}
.floatL, .floatR {
background: transparent;
}
.floatL a {
padding: 10px;
border: 10px transparent solid;
}
.floatL a:hover {
border-color: red;
background: white;
}
.floatR a {
padding: 10px;
}
.floatR a:hover {
background: red;
}
.floatR a:hover span {
background: white;
}
paddingでフレームを表現するシーンは結構多いです。Lopan.jpの画像を囲う斜線もpaddingの背景画像で対応しています。
※IE6では、ロールオーバー前とロールオーバー後で使用している背景画像や色が同じだからといって、ロールオーバー後の指定をはしょってはいけませんでした。
<div id="contents" class="clearfix"> <div class="floatL"><a href=""><span>フレームに画像を使用したリンク</span></a></div> <div class="floatR"><a href=""><span>フレームに画像を使用したリンク</span></a></div> </div>
a {
padding: 15px;
border: 0;
background: url(../img/stripe.gif);
}
a span {
padding: 5px;
background: white;
}
a:hover, a:hover span,
.floatR a, .floatR a span {
padding: 10px;
}
* html .floatR a:hover { background: url(../img/stripe.gif); }
.floatR a {
background: #ccc url(../img/stripe_img.gif);
}
.floatR a:hover {
background-color: red;
}
* html .floatR a:hover { background: red url(../img/stripe_img.gif); }
IE6で見ると、グリッドを敷いた要素(#contents)の幅が、テキスト要素分広がってしまったでしょう。
<div class="contents"> <p>左マージンに600pxを指定した幅250pxの要素</p> </div>
#contents {
width: 800px;
padding: 10px 0;
overflow: visible;
}
p {
width: 250px;
margin-left: 600px;
}
左マージンに600pxを指定した幅250pxの要素
これを解決するは、はみ出させるテキストに、はみ出した分のマイナスマージン(ここではmargin-right: -50px;)とともに、position: relative;を指定する方法がありました。
これをIE6で見ると、左側の画像は表示されなかったでしょう。
非常に基本的なケアレスミスですが、実際目の当たりにすると「なんで?なんで?」と、少し焦りました。img要素のwidth/heightはちゃんと指定するようにしましょう。
これはIE6/IE7では大丈夫なんですが、IE8以降や、Firefoxなどのモダンブラウザで起こります。
画像をボーダーで囲って表示すると顕著ですが、画像をそのまま配置すると下のように、画像の下に数pxの隙間ができてしまい、かっこわるいです。(※IE6対応とは関係ありませんが、よく使うので載せておきます。)
<div class="contents clearfix"> <div class="floatL"><img src="img/thumbnail.gif" alt="ダミー画像" width="180" height="130" /></div> <div class="floatR"><img src="img/thumbnail.gif" alt="ダミー画像" width="180" height="130" /></div> </div>
.floatL, .floatR {
background: white;
}
.floatL {
border: 10px blue solid;
}
.floatR {
border: 10px red solid;
}
これを解決するには、画像にdisplay: block;を指定するか、画像を囲っている要素にfont-size: 0;を指定すれば対応できます。
display: block;で解決したサンプル、赤枠の方がdivにfont-size: 0;で解決したサンプル<div class="contents clearfix"> <div class="floatL"><img src="img/thumbnail.gif" alt="ダミー画像" width="180" height="130" /></div> <div class="floatR"><img src="img/thumbnail.gif" alt="ダミー画像" width="180" height="130" /></div> </div>
.floatL, .floatR {
background: white;
}
.floatL {
border: 10px blue solid;
}
.floatL img {
display: block;
}
.floatR {
border: 10px red solid;
font-size: 0;
}
これをIE6/IE7で見ると、手前から順に、orange、violet、green、red、blue、yellowの順に配置されたでしょう。
IE6/IE7では、position: relative;が指定されている要素は、z-indexの指定がなければ、HTMLの記述順に(後から書かれたものほど上へ)配置される仕様でした。下のサンプルでは、section1(黄色の要素)、section2(緑色の要素)にはz-indexを指定していないので、後から記述されているsection2が、section1よりも手前へ表示されてしまいました。
<div id="contents"> <div class="section1"> <div class="inner1">上から3番目に表示される要素</div> <div class="inner2">一番手前に表示される要素</div> </div> <div class="section2"> <div class="inner1">上から2番目に表示される要素</div> <div class="inner2">一番背面に表示される要素</div> </div> </div>
#contents {
padding: 10px;
}
.section1, .section2 {
position: relative;
width: 450px; height: 250px;
}
.section1 { background: yellow; }
.section2 { background: green; }
.section1 .inner1, .section2 .inner1 {
position: absolute;
width: 200px; height: 200px;
}
.section1 .inner1 {
z-index: 20;
top: 50px; left: 100px; background: blue;
}
.section1 .inner2 {
z-index: 40;
top: 100px; left: 200px; background: red;
}
.section2 .inner1 {
z-index: 30;
top: -50px; left: 50px; background: orange;
}
.section2 .inner2 {
z-index: 10;
top: 0; left: 150px; background: violet;
}
これを解決するには、重なり合う要素がposition: relative;を指定した要素にまたがらないようにしないといけませんでした。
そのため、まずsection1、section2をposition: strict;に変え、#contentsの方にposition: relative;を追加します。これで、絶対配置する要素の基準が#contentsの左上になるので、あとはsection1、section2の左上基準だった配置位置を、#contentsの左上基準へと、変えるだけでした。
<div id="contents"> <div class="section1"> <div class="inner1">上から3番目に表示される要素</div> <div class="inner2">一番手前に表示される要素</div> </div> <div class="section2"> <div class="inner1">上から2番目に表示される要素</div> <div class="inner2">一番背面に表示される要素</div> </div> </div>
#contents {
position: relative;
padding: 10px;
}
.section1, .section2 {
position: static;
width: 450px; height: 250px;
}
.section1 { background: yellow; }
.section2 { background: green; }
.section1 .inner1, .section2 .inner1 {
position: absolute;
width: 200px; height: 200px;
}
.section1 .inner1 {
z-index: 20;
top: 60px; left: 110px; background: blue;
}
.section1 .inner2 {
z-index: 40;
top: 110px; left: 210px; background: red;
}
.section2 .inner1 {
z-index: 30;
top: 210px; left: 60px; background: orange;
}
.section2 .inner2 {
z-index: 10;
top: 260; left: 160px; background: violet;
}
特にIE6対応というわけではありませんが、上のサンプルで、この事が踏まえられている気がしたので、再確認のつもりで、サンプルを用意しました。
下のサンプルでは、relativeでtop: 50px;した要素は、移動する前の領域を残して表示のみ移動させるのに対し、absoluteでは、移動する前の領域ごと移動している事が分かります。
<div class="contents clearfix"> <div class="floatL"> <div class="inner"><p>元居た痕跡を残す、高さ100pxの要素</p></div> <p>relativeの下の要素</p> </div> <div class="floatR"> <div class="inner"><p>元居た痕跡を残さない、高さ100pxの要素</p></div> <p>absoluteの下の要素</p> </div> </div>
.contents {
position: relative;
}
p, .inner {
border: 5px #ccc solid;
background: white;
}
.inner p { border: 0; }
.inner {
top: 50px;
width: 290px;
height: 90px;
}
.floatL .inner { position: relative; }
.floatR .inner { position: absolute; }
元居た痕跡を残す、高さ100pxの要素
relativeの下の要素
元居た痕跡を残さない、高さ100pxの要素
absoluteの下の要素
例えばボックスなどの角を丸めるborder-radius、透明度を操作するopacity、テキストに影を付けるtext-shadow、ボックス要素に影を付けるbox-shadow、グラデーションを表現するgradient。CSS3でよく使う5大プロパティだと思います。これらをIE6で表現するには、画像を用意するか、重いjsを追加して無理くり実装するか、もしくわIE独自のfilterプロパティを使って対応していました。
<div class="contents"> <div class="borderRadius"><p>角丸を表現する「border-radius」</p></div> <div class="opacity"><p>透明度を表現する「opacity」</p></div> <div class="textShadow"><p>テキストに影を付ける「text-shadow」</p></div> <div class="boxShadow"><p>ボックス要素に影を付ける「box-shadow」</p></div> <div class="gradient"><p>グラデーションを表現する「gradient」</p></div> </div>
.contents div { width: 500px; margin: 10px; padding: 10px; border: 10px #ccc solid; }
.borderRadius {
border-radius: 1em;
}
.opacity {
opacity: 0.5;
}
.textShadow {
color: white;
text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.boxShadow {
border-color: white;
box-shadow: 0 1px 5px rgba(0,0,0,0.5);
}
.gradient {
color: white;
background: linear-gradient(left 45deg, red, orange, yellow, green, blue, indigo, violet);
background: -moz-linear-gradient(left -45deg, red, violet);
background: -webkit-gradient(linear, left top, right bottom, from(red), color-stop(0.2, orange), to(violet));
}
角丸を表現する「border-radius」
透明度を表現する「opacity」
テキストに影を付ける「text-shadow」
ボックス要素に影を付ける「box-shadow」
グラデーションを表現する「gradient」
IEでは角丸はjsを使わずしての対応は無理そうでしたので、代わりにその他の気になるfilterも試してみました。
※下のサンプルでは、IE6/IE7でテキストシャドウが出ていないのと、透過画像が表示されてないですX-(。
<div class="contents"> <div class="borderRadius"><p>角丸を表現する「border-radius」</p></div> <div class="opacity"><p>透明度を表現する「opacity」</p></div> <div class="textShadow"><p>テキストに影を付ける「text-shadow」</p></div> <div class="boxShadow"><p>ボックス要素に影を付ける「box-shadow」</p></div> <div class="gradient"><p>グラデーションを表現する「gradient」</p></div> <div class="bgOpacity"><p>背景の透明度を変える</p></div> <div class="grayScale"><p>グレースケールで表示する</p></div> <div class="mirror"><p>要素を反転させる</p></div> <div class="rotate"><p>要素を回転させる</p></div> <div class="alphaImg"><p>透過画像を表示する</p></div> <div class="horizontal"><p>縦書きのサンプル<br>縦中横→平成<span class="tcy">24</span>年</p></div> </div>
.opacity {
filter: alpha(opacity=50);
}
.textShadow p {
filter: dropshadow(Color="#33000000", Positive=1, OffX=1, OffY=1)
}
.boxShadow {
filter: progid:DXImageTransform.Microsoft.Shadow(Color="gray", Direction=135, Strength=3);
}
.gradient {
color: white;
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorstr="red", EndColorstr="violet");
}
.bgOpacity {
background: transparent;
filter: progid:DXImageTransform.Microsoft.Gradient(StartColorstr="#99feec02", EndColorstr="#99feec02");
}
.grayScale {
color: white; background: url(../img/background.jpg);
filter: progid:DXImageTransform.Microsoft.BasicImage(GrayScale=1);
}
.mirror {
filter: progid:DXImageTransform.Microsoft.BasicImage(Mirror=1);
}
.rotate {
filter: progid:DXImageTransform.Microsoft.BasicImage(Rotation=2);
}
.alphaImg {
background: transparent url(../img/grid.gif) left top;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../img/lopan.png");
}
.horizontal {
writing-mode: tb-rl;
}
.horizontal .tcy {
layout-flow: horizontal;
}
角丸を表現する「border-radius」
透明度を表現する「opacity」
テキストに影を付ける「text-shadow」
ボックス要素に影を付ける「box-shadow」
グラデーションを表現する「gradient」
背景の透明度を変える
グレースケールで表示する
要素を反転させる
要素を回転させる
透過画像を表示する
縦書きのサンプル
縦中横→平成24年