モードの変更

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

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

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

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

/* 宣言ブロックが分かれていれば IE6 でも !important の動作は仕様通り */
.box {
  height: auto !important; /* 有効 */
}

/* !important によって上書きされるので 100px の指定は無効になる */
.box {
  height: 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さんです。