IE7 で box-sizing を利用したレイアウトを実現する

CSS の box-sizing プロパティはリキッドレイアウトのときに有用なプロパティだ。値に box-sizing を指定すると padding や border を含めた値で width/height を計算してくれるので、パーセント値を指定する場合は特に便利だ。box-sizing は多くのモダンブラウザで使えるほか、Internet Explorer 8 でも使用することができる。

問題は中途半端な位置づけにある Internet Explorer 7 だが、次のような解決策を見つけた。expression プロパティを利用して、レイアウトされた時点での値を計算している。

.box-sizing-ie7 {
    /* emulates width: 33% */
    width: expression((this.parentNode.clientWidth/3 - parseInt(this.currentStyle['paddingLeft']) - parseInt(this.currentStyle['paddingRight'])) + 'px');
}
Emulate CSS box-sizing in IE7 | maratz.com

LESS を使って簡単に書く

このテクニックを LESS CSS を使ってすっきりと書いてみよう。

.box-sizing(@boxmodel) {
    -webkit-box-sizing: @boxmodel; // for 1.24% (2013-04) and Android 2.3
    -moz-box-sizing: @boxmodel; // still needed (2013-04)
    box-sizing: @boxmodel; // Chrome 9+, Explorer 8+, Opera 7+, Safari 5.1+
}

.ie7-outer-width-rate(@width) {
    *width: ~"expression((this.parentNode.clientWidth * @{width} - parseInt(this.currentStyle['paddingLeft']) - parseInt(this.currentStyle['paddingRight'])) + 'px')";
}

.ie7-content-width(@width) {
    *width: ~"expression((@{width} + parseInt(this.currentStyle['paddingLeft']) + parseInt(this.currentStyle['paddingRight'])) + 'px')";
}

それぞれ、

  • .box-sizing はベンダプリフィクスを入力する手間を省くミックスイン
  • .ie7-outer-width-rate は box-sizing: border-box の状態の幅を割合で指定するミックスイン。パーセント値の代わりに単位のない値を指定する(パーセント値に 100 を掛けた値)
  • .ie7-content-width はフォーム部品などで box-sizing: content-box の状態の幅をピクセル値で指定するミックスイン(ただし指定は単位なしで行う)

である。

次のように使う。

.item { float: left; width: 31.944444%; margin: 0 0.6944444% 10px; padding: 9px 10px;
    .box-sizing(border-box); .ie7-outer-width-rate(0.3194); }

#search-submit { .box-sizing(content-box); width: 32px; .ie7-content-width(32); }

問題点

この方法では border-width までを含めて計算する方法が分からなかった。 this.currentStyle.borderLeftStyle と this.currentStyle.borderLeftWidth を組み合わせて判定してみたがうまくいかなかった。