CSSでbox-sizingの値をborder-boxで指定することで、親要素の幅を超えて子要素がはみ出したり、カラム落ちするという悩みを解決できました。
CSSでbox-sizingを指定する書き方は簡単ですが、box-sizingの値で使用するborder-boxとcontent-boxが形成するボックスモデルを理解することで、box-sizingの使い方を深めておきたいと思いました。
CSSのbox-sizingとは
box-sizingとは、ボックスの大きさで必要とする幅と高さの算出方法を指定できるCSSのプロパティです。
HTMLでマークアップした要素の幅と高さをCSSではwidthで横幅、heightで高さを指定しますが、指定した要素に必要なら幅と高さの指定以外にもコンテンツ外側にpaddignやborderを指定することがあります。
このときCSSのbox-sizingは、要素に指定したpaddignやborderの領域をコンテンツ内に「含めるか含めないか」を指定して変更ができるCSSのプロパティです。
box-sizingに使用する値を理解する
CSSのbox-sizingプロパティに値を指定することで、幅と高さを決めた要素のボックス領域を設定することができます。
CSSのbox-sizingに使用する値は主に2つです。
- border-box
- content-box
「border-box」と「content-box」2つの値をCSSで実際に書く場合
box-sizing:border-box;
box-sizing:content-box;
box-sizingに使用する値の書き方は簡単ですが、2つの値を使用するそれぞれのボックスにpaddingやborderが指定してある場合には、padding領域とborder領域の扱い方が2つの値ごとに違うボックスの算出方法で適用されます。
box-sizing:border-box
CSSでbox-sizing:border-boxを指定した場合には、どんなボックス領域になるかを理解できるようにします。
<div class="box-sizing">
<div class="border-box">border-box</div>
</div>
.box-sizing {
background: skyblue;
padding: 30px;
width: 50%;
margin: 0 auto;
}
.border-box {
width: 100%;
background: pink;
text-align: center;
margin: 30px auto;
padding: 20px;
border: 10px solid #333;
box-sizing: border-box;
}
CSSでwidth: 50%の幅にした親要素のボックスの中で子要素のdivがwidth:100%の幅になるようにしてます。
そしてbox-sizing:border-boxを子要素のdivに指定します。表示結果は以下の画像です。
box-sizing:border-boxを指定した子要素のボックスは、marginが上下に30pxとpaddingが20px指定してあり、borderも10pxで指定してあります。
このときのpaddingとborderは、「border-box」という文書を表示するコンテンツ領域にパディングとボーダーが含まれたボックスとして余白が広がります。
box-sizingの使い方としては、値にborder-boxを指定して使用することで子要素が親要素から突き抜けたり、カラム落ちするのを防げるので1番理解しておきたい使い方です。
しかしbox-sizingの使い方をbox-sizing:border-boxではなくbox-sizing:content-boxの値で指定し直すと表示結果が変わるので、その変化でbox-sizingについて理解が深ます。
box-sizing:content-box
CSSでbox-sizing:content-boxを指定する場合もbox-sizing:border-boxで指定したときと同じHTMLとCSSを使用してます。
<div class="box-sizing">
<div class="content-box">content-box</div>
</div>
一箇所だけ違うのはCSSでbox-sizingプロパティの値をcontent-boxにしたことです。
.box-sizing {
background: skyblue;
padding: 30px;
width: 50%;
margin: 0 auto;
}
.content-box {
width: 100%;
background: pink;
text-align: center;
margin: 30px auto;
padding: 20px;
border: 10px solid #333;
box-sizing: content-box;
}
box-sizing:border-boxからbox-sizing:content-boxに値を指定し直したことで、ボックスの表示は以下の画像のような結果になります。
CSSでbox-sizingの値をcontent-boxにすると親要素の幅を元気よく、はみ出してくれます。
今回のCSSで要素の幅を指定するイメージとしては、親要素の幅を50%にしたボックスの中に幅100%の子要素のボックスが収まるようにしたのですが、border-boxとcontent-boxではボックス表示が変わるのですね。
box-sizingの値をcontent-boxにしたことで親要素の幅を子要素のボックスが突き抜けてくれる原因は、子要素で指定したpaddingとborderがコンテンツの外側で領域を作り算出されるためです。
box-sizingを指定してない場合もpaddingとborderはコンテンツの外側で領域を作ります。これは初期値の設定が「content-box」だからです。
border-boxとcontent-boxの違い
content-boxの場合は、コンテンツ領域の外側でpaddingとborderが算出される。
border-boxの場合は、paddingとborderがコンテンツ領域の内側で算出される。
けっきょくpaddingとborderをボックスモデルでどう扱うかという違いになるのですが、検証ツールを使用するとborder-boxとcontent-boxの違いがわかりやすく理解も深まります。
先述したCSSでbox-sizingの値をborder-boxとcontent-boxどちらで指定する場合でも、width100%の幅でpadding:20pxとborder:10pxでした。
つまりpaddingの幅は左右で40px、borderは左右で20pxで合計60pxがコンテンツ領域に含まれるか、含まれないかで算出されます。
上の2つの画像で青い枠がコンテンツ領域ですが、上側画像はborder-boxを指定してるので、幅が500です。
一方で下側の画像は、content-boxの場合で、borderとpaddingの合計幅40pxがコンテンツ領域に含まれるので幅560になるわけです。
そのためwidth100%にしてもborder-boxの場合は親要素に収まることができ、content-boxの場合は親要素からはみ出してくれるという違いが誕生します。
box-sizing:border-boxで解決したこと
ここまでの内容が理解できてくるとbox-sizingの値にはborder-boxを優先して使いたくなります。
私自身も優先して使いたくなり、box-sizing:border-boxで解決したことを2つくらい簡単に紹介してこの記事を終わりたいと思います。
floatでカラム落ち
box-sizing:border-boxで解決したこと1つめは、width50%のボックス幅の中に、同じwidth50%のfloatボックスを横並びにして遊んでたときにカラム落ちを解決できたこと。
カラム落ちしてやる気をなくした私はfloat遊びをやめようかと。だけど忘れてたbox-sizing:border-boxを思い出して指定すると…
カラム落ちした2つのボックスが横に並んでくれた。
box-sizing:border-boxをCSSでたったの一行追加しただけで解決することができた瞬間でした。
リセットCSSにborder-box
box-sizing:border-boxで解決したこと2つめは、ほとんどが要素からはみ出してしまう問題ばかりです。
Webページを作って遊んでると、ちょいちょいの確率で一部分だけはみ出す要素ができてしまうことがあります。
効率良いやり方ないかなと調べているとリセットCSSにbox-sizing:border-boxを記述しておけば良いらしい。
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
セレクタをアスタリスクにして擬似要素用にもbox-sizing:border-boxとしておくと良いようです。
ベンダープレフィックスも必要なら適宜で指定します。
こうして全ての要素にbox-sizing:border-boxを適用できるように、Webサイトの作成を始める段階でやっておくと、コーディング途中で悩まされることが解決できます。
まとめ
CSSでbox-sizingのborder-boxとcontent-boxを理解できるようにしてみましたが、box-sizingの値ではborder-boxの使用がほとんどです。
特にWebサイトをレスポンシブ化して小さいスマホ画面に対応するときは、コンテンツ領域にborderとpaddingを含めて表示できることが、とても便利です。
box-sizingを指定してないと初期値がcontent-boxなので、box-sizing: border-box;と指定してWebサイト作成を頑張ってください。