boxレイアウトの救世主「box-sizing」

divなどのboxのレイアウトは、値を変えようとすると何かと四苦八苦しますよね。
今回は柔軟なレイアウトを組むことができるプロパティbox-sizingがテーマです。
「とにかくもうboxサイズの微調整に悩まされたくないんだ…」そんなあなたはぜひご一読ください。
1)box-sizingとは?
2)box-sizingの設定方法
3)selectの落とし穴
1)box-sizingとは?
まずはbox-sizingがどんな設定ができるかをおさらいしましょう。
◆box-sizing
| content-box | 初期値:padding、borderをwidth、heightに含めない |
|---|---|
| border-box | padding・borderをwidth・heightに含める |
| inherit | 親要素の値を継承する |
CSS標準仕様における規定値は、content-boxです。
ご存知のように、boxのサイズはコンテンツ、padding、borderによって構成されます。
そのため、コンテンツそのもののサイズ以外にもpadding、borderのサイズを考慮してboxの合計サイズを割り出さなければなりません。(もしくは、設定したいサイズから逆算)
そのため、ちょっとwidthやheightの値を変えただけでレイアウトが崩れて計算しなおして…ということが発生します。
こうしたちょっとした手間が続くと、まあまあの労力につながってしまいますよね。
でも、box-sizing:border-box;を設定することによって、毎回計算しなおすという労力から解放されるのです!
※contents、padding、borderの詳細については、以下の記事をご参照ください。
インライン要素とpaddingの微妙な関係♡
◆対応ブラウザ、バージョン
box-sizingは、css3から追加された新しいプロパティです。対応するブラウザやバージョンは意外と幅広く、IE8以降からサポートしてくれるなど比較的使いやすいプロパティです。
- chrome 10~
- Firefox 29~
- IE 8~
- safari 5.1~
- iOS Safari 5.0~
- Android Browser 4.0~
これだけ対応していればほぼ問題なく使えるのではないでしょうか。
もう少し対応範囲を広げたい、より確実に適用させたい場合は、以下の対応も合わせて行いましょう。
●Firefox28、iOS4、Android2.3以前のブラウザには、ベンダープレフィックスを付与(後述「「box-sizing」の設定方法」参照)
●HTML5、css3をIE8に対応させるには、以下の対応をしておくとより安心です
http://www.9142.net/blog/2012/05/02/html5-ie/
2)box-sizingの設定方法
box-sizingの使い方は他のプロパティ同様、個別にも全体にも設定することができます。
◆個別にbox-sizingを設定する場合
.boxSizing {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
※より広範囲のブラウザやバージョンに適用させるため、ベンダープレフィックスも付与します。
上記のCSSを使用すると、box-sizingの値をborder-boxに揃えたい要素に対して「.boxSizing」のclassを付けるだけで、実装することができます。
上記で設定しているborder-boxはpadding・borderをwidth・heightに含める設定でしたね。
そもそも、値が変更されることによって毎回計算しなおさなければならないという手間は、CSS標準仕様であるcontent-boxの性質によって発生していました。
上記のソースのようにborder-boxに設定することでコンテンツ、padding、borderの値がどう変化しようとwidthやheightの値は変わらないので、カラム落ちの心配がありません。
cssの設定を統一するためには、個別に設定するというより次に説明する全体に設定する方法の方をお勧めします。
◆全体にbox-sizingを設定する場合
よく見られるのはユニバーサルセレクタを使用する方法です。
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
便利なものの、ユニバーサルセレクタは速度にやや影響を及ぼすことがあるという懸念点も指摘されていました。(現在はそれほど心配はないようですが…)
以下の記述は、その点を改善したものです(※)。(2014年8月現在)
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
こちらは速度に対する対処の他にも、プラグインによる変更にも柔軟に対応できる点が利点のようです。
あまり見られない設定なので少々難しく感じますが、ベンダープレフィックスもいらないとのことで、ソースが軽い点もポイント高いです。
3)selectの落とし穴
前述の通り、box-sizingの初期値は基本的にcontent-boxです。
しかし、selectの初期値に関しては、border-boxになっています。
なので、「cssは同じなのにinputとselectで幅が違う!」というようなことが起こりえます。
たとえばこんな感じです。
下のinputとselectには全く同じcssを設定していますが、幅と高さに違いが出ていますね。
css
input,select {
width:200px;
height:30px;
padding:5px;
border:1px solid #999;
background-color:#FFF;
}
この現象を図にすると以下のようになります。
inputの方はの初期値がcontent-boxなので、widthとheightを設定したサイズ(width:200px; height:30px;)にpaddingとborderが追加されています。
一方、selectはborder-boxが設定されているので、widthとheightで設定したサイズ(width:200px; height:30px;)内にpaddingとborderが含まれてしまっています。
これらを同じcssで幅・高さをそろえたい場合は、以下のように記述します。
css
input,select {
width:200px;
padding:5px;
border:1px solid #999;
background-color:#FFF;
box-sizing:border-box;
}
このようにブラウザごとの設定を把握し、同じ初期値にしておくことで、cssの調整で「ハマる」ことも減ってきます。
効率よくコーディングを進められるよう、css3を使用できる場面ではどんどん活用していきましょう。
なぽりたんが書きました。



今日のひとこと:現在公開中の『ゴーン・ガール』、観たいけどビビリなので悩み中(。・ε・`。)