IE6の疑似min-heightは奇跡のCSSトリック

“昔々あるところに……。” CSS昔話 Advent Calendarの8日目。

IE6ではmin-width/max-width/min-height/max-heightのCSSプロパティーに対応していないが、min-heightに限ってはIE6でも疑似的に同じ表現をすることができた。

.box {
  min-height: 100px;
  height: auto !important;
  height: 100px;
}

Easiest cross-browser CSS min-height

min-heightに対応しているモダンブラウザでは.boxmin-height: 100pxによって100px以上の高さが保証されるとともに、height: 100pxはその前の行のheight: auto!importantによって上書きされ、コンテンツが100pxに収まらない場合はコンテンツ量に応じたボックスサイズとなる。

IE6ではまず未対応プロパティーのmin-height: 100pxは無視される。さらにIE6では、 同一の宣言ブロック内に同じプロパティーが指定された上で、先に書かれたプロパティーに!importantがついている場合、!importantを無視してあとに書いた値で上書きする。つまりheight: 100pxのみが適用された状態になる。この!importantを無視する挙動はheightに限らず他のどんなプロパティーでも同じだったと思う。

/* IE6での解釈 */
.box {
  min-height: 100px; /* 無効 */
  height: auto !important; /* 無効 */
  height: 100px; /* 有効 */
}

宣言ブロックが分かれていればIE6でも!importantは仕様通りに解釈される。

/* 宣言ブロックが分かれていればIE6でも期待通り */
.box {
  height: auto !important; /* 有効 */
}
...
.box {
  height: 100px; /* !importantによって上書きされるので100pxの指定は無効になる */
}

CSSの仕様上、heightプロパティーに固定値が指定されるとボックスの高さはその値で動かなくなり、コンテンツがその値に収まらなければoverflow: visibleの初期値に従い下方向へはみ出して表示される。

しかしIE6ではそうならない。コンテンツが.boxの高さに収まらなくなると、.boxの高さに固定値が指定されていたとしてもコンテンツ量に応じて.boxの高さが伸びていく。コンテンツが収まるときは.boxは100px未満にはならない。あたかも min-heightheight: autoが指定されているかのように振る舞う。

この「同一宣言ブロック内の同一プロパティーの!importantが無視されるバグ」と「heightのサイズ算出のバグ」の併せ技によって、IE6とモダンブラウザで同じ表現が可能になるというわけだ。

これは奇跡の組み合わせだと感じる。ボックスのサイズ算出のバグが起こるのはheightだけで、widthではそのようなことは起きなかった。IE6でheightだから可能だったのだ。

このスニペットが日本のブログで紹介されると瞬く間に広まったが、IE7やIE8でどう解釈されるのかを懸念する人もいくらかいた。IE7以上はmin-heightに対応しているので、!importantがIE6同様に無視されるとheight: 100pxが適用されてmin-heightの記述が無意味になるのでは?という懸念だ。

しかし実際はこの!importantのバグはIE7で解消され、モダンブラウザと同じくmin-height: 100pxheight: auto!importantが解釈されて期待通りの表示となるのであった。

CSSの文法としてvalidで、IE6のみにターゲットをしぼり、他のブラウザに影響を与えず、記述も非常にシンプル。このスニペットも「CSSハック」ではなく「CSSトリック」と呼びたい。まるで初めからそこにあったかのような、かつ手のひらにちょうど収まる感じがする、そんな存在感のあるスニペット。今では全く使わなくなったが、あの頃を思い出すと暖かい気持ちになれる気がするのだ。気がするだけだが。


特定の条件で!importantをなかったことにできるIE6ってやっぱりやばかったなと思う。 HTMLコメントを地のテキストに勝手に変換するバグといい、なかなかの逸材だったと認めざるを得ない。

CSS昔話 Advent Calendarでは今日以後のエントリでも、IE6のような10年以上前のブラウザ達がいかに奇妙なレンダリングをしていたかを振り返ることができるだろう。CSSハックとして紹介していた頃と決定的に違うのは、それらがモダンブラウザ時代の目線で語られることだ。単なる苦労話の共有におさまらない、時世を反映した回顧録。今後どんな話が出てくるのか、本当に楽しみにしている。

前回のエントリでは 古傷えぐってしまって申し訳ないと思った。だけど人は過去を乗り越えていける……強い生き物だと思うから……。

9日目は @ksk1015さんです。