【CSS】box-sizing:border-boxを使って要素がはみ出ないようにする方法

box-sizing:border-boxの使い方

今回は「要素からpaddingの部分がはみ出てしまう」「線がはみ出てしまう」というような問題をbox-sizingプロパティにより簡単に解決する方法を紹介します。CSS初心者の方でも分かるように box-sizingの意味から、使い方各ブラウザの対応状況まで解説します。丁寧に解説していくので、中級者〜上級者の方は必要に応じて読み飛ばして頂ければと思います。

1. box-sizingとは?

box-sizingとは最新のCSS規格「CSS3」から追加されたプロパティです。このプロパティにより「要素の幅(width)と高さ(height)の中にpaddingとborderを含めるかどうか」という設定ができます(どういうことか後で図解します)。

1-1.box-sizingで指定する3つの値

box-sizingでは以下の3つの値を取ります。

  • box-sizing: content-box; ←初期値! paddingとborderを幅と高さに含めない
  • box-sizing: border-box; paddingとborderを幅と高さに含める
  • box-sizing: inherit; 親要素のborder-boxの値を引き継ぐ

それぞれの値で具体的にどのような違いが出てくるのか見ていきましょう。

1-2. 値がcontent-boxの場合

paddingとborderを幅(width)と高さ(height)に含めない

box-sizing: content-boxは初期値です。何も指定をしていないときは、この値を取っているわけですね。例として幅(width)で考えてみましょう。

box-sizing:content-boxの場合

値がcontent-boxの場合、widthで指定する幅の中にはpaddingとborderは含まれません

要素が作り出す幅は、width + padding + borderの太さ + marginになります。pxでwidthやpaddingを指定する分にはこれでも別に良いのですが、問題はレスポンシブデザインのために%で指定するときです。

content-boxの欠点の話

親要素と子要素の幅の関係

%指定をするとき要素の幅の合計は100%になっていなければなりません(100%を超えると親要素からはみ出てしまいデザインが崩れます)。

なのでmarginを左右で30%に、paddingを左右で30%に、widthを40%に、などとして要素の作る幅を計100%にすれば、親要素にピッタリとはまっていい感じになるわけですね。しかし計100%にするためには、一部の値だけをpx指定にするわけにはいきません。paddingだけ10pxにしたら計100%にできなくなってしまいます。

box-sizing: content-boxの状態で%指定したときに、あきらかに問題になるのはborderを含めるときです。borderの太さは%指定ができません。

border

たとえばwidthとmarginとpaddingで計100%であっても、borderの太さを5pxにするとその分だけ親要素からはみ出てしまうわけですね。

このようにpx指定しなければならないborderが入ると、要素が親要素にカチッとはまられなくなります。また「widthとmarginを%で指定して、paddingだけをpx指定」ということが難しくなります。(計100%にならず、親要素からはみ出てしまったり、アンバランスなスペースができてしまったりします)。これがcontent-boxの欠点です。

ポイント

【content-boxだと…】

  • 要素の幅や余白を%で指定したいときに、borderを加えると親要素からはみ出てしまうことがある
  • marginとwidthを%で指定して、paddingだけpxで指定すると親要素からはみ出てしまうことがある

1-3. 値がborder-boxの場合

paddingとborderを幅(width)と高さ(height)に含める

border-box

box-sizing: border-boxとすると、paddingとborderがwidthとheightの中に含まれるようになります。

つまりwidth: 50pxと決まっているなら、paddingとborderもその50pxの中に含まれるようになるのです。

線とpaddingをどれだけ大きくしても要素の大きさは変わらない

そのため、線(border)とpaddingをどれだけ大きくしても、要素の大きさ(widthとheight)は変わりません。

線が太くなれば、その分だけ中身が小さくなる

padding:0でborderだけで画像を囲った場合、borderを太くしてもwidthの値は変わりません。代わりに要素の中身自体が自動で小さくなります。「width」 – 「borderの太さ」=「中身の大きさ」となるわけですね。

border-boxはレスポンシブデザインで便利

border-boxは幅や余白を%で指定したいときに便利です。%指定はレスポンシブデザインデザインを作るうえでは欠かせません(ウェブページを見る端末の大きさに応じて、要素の大きさを調整できるからです)。ではなぜbox-sizingは%指定をするときに便利なのでしょうか。その理由は「親要素にピッタリはまりやすくなるから」です。言い換えると横の%合計を100%にしやすくなるのです。

Box sizingのmarginとpaddingの考え方 02

widthの中にpaddingとborderが含まれるので「width」と「左右のmargin」の合計だけを100%にすれば、親要素にピッタリとはまります。borderとpaddingにどんな値を指定しても、親要素からはみ出てしまう心配がなくなるのです。

1-4. content-boxとborder-boxの違いの例

では実際にcontent-boxとborder-boxの違いをコードで書いて見てみましょう。分かりやすくするために要素はオレンジ色に、親要素はグレイにします。

HTMLコード
<div id="contentbox"><!--content-boxの親要素-->
  <p>content-box</p>
</div>

<div id="borderbox"><!--border-boxの親要素-->
  <p>border-box</p>
</div>
CSSコード
#contentbox, #borderbox {
	/*以下、親要素を見やすい設定に*/
	background: silver;
	padding: 10px 0;
}

#contentbox p {
	box-sizing: content-box;
	}

#borderbox p {
	box-sizing: border-box;
	}

#contentbox p, #borderbox p{
/*どちらも同じ幅・余白設定に*/	
	width: 90%;
	margin: 5%;
	padding: 10px;
	border: solid 5px black;
	background:orange;
}
ブラウザ表示

ブラウザ表示例

↑補足情報を書き込んでいます。content-boxの場合、width + 左右border + 左右padding + 左右margin = 100%になっていないと親要素にきれいに収まりません。border-boxの場合、width + 左右padding = 100%になっていれば、paddingとborderがどんな値であろうと親要素にきれいに収まります

このようにborder-boxを使うことで、%での幅・余白指定がものすごく楽になるのですね。

1-5. 値がinheritの場合

親要素のborder-boxの値を引き継ぐ

box-sizing: inheritと指定した場合には、親要素にbox-sizingの指定を引き継ぐことになります。もし親要素に対してbox-sizingを特に指定していないのであれば、親要素は初期値のcontent-boxになっているはずです。ですのでinheritに指定すると、content-boxが適用されることになります。とはいえ、あまりこの値を指定することはないかもしれませんね。

2. box-sizingの対応ブラウザと書き方の注意点

box-sizingプロパティはCSS3から登場しました。では、古いブラウザではどのくらい対応しているのでしょうか。ちなみに「対応していない」=「全要素content-boxになっていてborder-boxを使えない」ということになります。

2-1. 対応ブラウザ

ブラウザ種類 対応バージョン
Google Chrome バージョン1以降
IE IE8以降
Firefox バージョン2以降
Safari バージョン3以降
Opera バージョン8以降

メジャーのバージョンではほとんど全て対応していると思って良いでしょう。IE7にどうしても対応させたい場合は『IE7以下でbox-sizingを使いたい』という記事が参考になりそうです。

2-2. box-sizingが効かない?

古いAndroid端末などで、ブラウザが対応バージョンなのに「box-sizingが効かない」という場合があります。対処法は簡単で以下のベンダープレフィックスを書くことで解決します。

2-3. ベンダープレフィックスをつけよう

box-sizing: border-boxを使いたいときは、古いバージョンのブラウザに対応させるために、念のためベンダープレフィックスをつけておきましょう。

ベンダープレフィックスとは?

※プロパティ名の前に書く「-webkit-」「-moz-」「-o-」「-ms-」などの文字のことです。これを書くことで古いブラウザにCSS3のプロパティを対応させることができたりします。「-webkit- ⇒ Google ChromeとSafariに対応させるためのもの」「-ms- ⇒ IEに対応させるためのもの」というように1つ1つ決まっています。なお、古いブラウザに対応させるといっても、さきほどの表の対応バージョン以前まで対応させられるわけではありません。あくまでも対応バージョンの中で、古いバージョンにも対応させるためのものなわけですね。

ベンダープレフィックスをつけた指定

具体的には以下のように指定することをおすすめします。

-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;

コピペして使うのが良いでしょう。

3. border-boxを全ての要素に適用する方法

レスポンシブデザインのウェブサイトを作るのであれば、全ての要素をあらかじめbox-sizing: border-boxにしておくと楽でしょう。その方が作業中に混乱しづらくなります。具体的にはCSSに以下のように書いておきます。セレクタに*(アスタリスク)を使うと「全ての要素に対して適用させる」という意味になります。

* {-webkit-box-sizing: border-box;
   -ms-box-sizing: border-box;
   -moz-box-sizing: border-box;
   -o-box-sizing: border-box;
   box-sizing: border-box
	}

4. まとめ

ここまでの内容をまとめておきます。

まとめ
  • box-sizingプロパティでは、widthとheightに「paddingとborderを含めるかどうか」を決める
  • content-box:含めない
  • border-box:含める
  • 値をcontent-boxにすると、幅や余白を%指定したいときには不向き(親要素からはみ出てしまったりしやすい)
  • 値をcontent-boxにすると、borderとpaddingのぶんの大きさがwidthに含まれるため、幅と余白の%指定が楽になる
  • border-boxを指定するときは、古いブラウザ対応のためベンダープレフィックスをつけておく
  • 「*」を使って全ての要素に対してborder-boxを指定しておくと楽
サルワカ