1. TOP
  2. リファレンス
  3. paddingや横幅100%を使うと、子要素が親要素からはみ出る現象の解決方法

paddingや横幅100%を使うと、子要素が親要素からはみ出る現象の解決方法

子要素のwidthが親要素のwidthより小さいはずなのに、なぜか子要素が親要素をはみ出してしまう場合があります。

そんな時、原因は子要素に設定されているpaddingやborderである場合が多いです。

例えば下記のような例を見てみましょう。

<div id="demo_110-1">
   <div id="demo_110-2">
   </div>  
 </div>
 #demo_110-1{
   width: 250px;
   height: 100px;
   background-color: tomato;
 }
 
 #demo_110-2{
   width: 250px;
   height: 50px;
   padding: 5px;
   background-color: green;
 }

親要素も子要素も横幅は一緒なのにもかかわらず、緑色の子要素が、オレンジの親要素よりはみ出していますね。

これは子要素にpaddingが設定されていることが原因で、要素にpaddingやborderが設定されると、そのぶんボックスの横幅が大きくなってしまうからなんです。

ボックスの仕様を理解しよう

CSSの仕様では、widthは「ボックスのなかのコンテンツの横幅」を示します。

ボックス全体の横幅は、コンテンツの横幅だけではなく、paddingとborderの幅もあわせたものになります。

つまりwidthが500pxのボックスがあるとして、なにもしなければボックスの横幅は500pxのですが、padingを左右に10pxずつつければその分ボックスが20px広がり、520pxの横幅に広がります。

<div id="demo_110-1">
   <div id="demo_110-2">
   </div>  
 </div>
 #demo_110-1{
   width: 250px;
   height: 100px;
   background-color: tomato;
 }
 
 #demo_110-2{
   width: 250px;
   height: 50px;
   padding: 5px;
   background-color: green;
 }

このように、paddingを設定したほうはその分ボックスの横幅が伸びていのがわかります。※ボーダーでも同様に横幅が伸びます。

つまり、子要素が親要素をはみ出さないようにするには、子要素のpaddingとborderがボックスの横幅に加えられることを考えて、widthを決めなければなりません。

これだと計算するのが大変です。そこで後述していきますが、簡単に解決できる方法があります

box-sizingプロパティを使おう

box-sizingプロパティを使うことで、widthとheightにpaddingとborderを含めるかどうかを変更することが出来ます。

box-sizingプロパティはCSS3から追加された比較的新しいプロパティで、この値を変更することでwidthとheightにpaddingとborderを含むようにすることができます。

以下のようにして使います。

box-sizing: 値;

値にはcontent-boxborder-boxinheritなどを指定します。

content-box

初期値です。何もしていなければこの値になります。

box-sizing: content-box;

widthとheightの値にpaddingとborderは含まれません。最終的なボックスの大きさは、widthとheightに、paddingとborderの値を足したものになります。

content-boxの問題点

content-boxにはいくつかの問題点があります。

上述したように、思いがけず親要素をはみ出してしまったりするというのが一つですが、もう一つ問題があります。

それは要素の横幅を%で指定した時に起こるのですが、要素の横幅を%で指定する場合は、幅の合計は100%になる必要があります。なぜなら合計が100%を超えると、親要素より大きい事を意味し、はみ出してしまうからです。

ここで問題になるのが、「borderの太さは%を使うことができない」という点です。

ボックスの横幅はwidthと、ボーダーとパディングの合計ですが、ボーダーはpx指定しかできないため、横幅80%、パディング10%、ボーダー5pxという風に、ボーダーだけpx指定をすることになります。

これで横幅の合計を100%にすることができないため、はみ出してしまったり、逆に不要な余白ができてしまったりすることになってしまいます。

border-box

値にborder-boxを指定すると、widthとheightにpaddingとborderが含まれるようになります。つまり、設定したwidth、heightの中でpaddingやborderをとるようになります。

box-sizing:border-box;

例えば、widthが100%のボックスにpaddingを10pxとすると、ボックスの横幅はかわらず内側にpaddingが適用されます。

<div id="demo_112-1">
 </div>
#demo_112-1{
   box-sizing:border-box;
   width: 100%;
   height: 100px;
   padding: 10px;
   background-color: tomato;
 }

また、%で横幅を指定したい場合も、widthに100%を設定してしまえば、あとはどんなpaddingとborderを取ってもはみ出すことがないので簡単に使うことができます。

<div id="demo_113-2">
 </div>
 
#demo_113-2{
   margin-top: 10px;
   box-sizing:border-box;
   width: 100%;
   height: 100px;
   padding: 10%;
   border: 5px solid #000;
   background-color: green;
 }

横幅を%で指定する方法はレスポシンブデザインでよく使わるので、このborder-boxを指定しているサイトも増えてきています。

値がinheritの場合

inheritとすると親の要素の設定を引き継ぎます。

box-sizing:inherit;

box-sizingを使う機会は増えてきている

box-sizingは比較的新しいプロパティですが、ほぼ全てのブラウザが対応しています。

対応状況はこちら:https://caniuse.com/#search=box-sizing

稀に、古いアンドロイドで効かないということがありますが、その場合はベンダープレフィックスで解決できることが多いです。

-webkit-box-sizing: border-box;
box-sizing: border-box;

あまり古くない限り問題なく動作するのでどんどん使ってOKです。

border-boxは使い勝手が良くレスポンシブデザインと相性が良いため、最近のサイトでは全ての要素にborder-boxが適用されていることが少なくありません。

全要素に適用するには下記のように書くと良いでしょう。

*, *:before, *:after {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

まとめ

  • 子要素にpaddingやborderが設定されていると、親要素をはみ出すことがある
  • デフォルトでは、ボックス全体の横幅は、コンテンツの横幅だけではなく、paddingとborderの幅もあわせたものになる
  • box-sizingプロパティを使うと、widthとheightにpaddingとborderを含めるかどうかを変更することができる
  • border-boxにすると、widthとheightにpaddingとborderが含まれるようになる
  • box-sizingを使う機会は増えてきている