この記事では子要素が横幅100%にも関わらず、親要素をはみ出してしまう原因と、対処法であるCSSの「box-sizing」について解説します。
横幅100%だったら親要素と一緒の横幅になるんじゃないの?なんではみ出す事があるんだ?
その考えは基本的には間違ってないよ!でも横幅(width)の外側にはボーダーや余白があるから、100%だとはみ出ることがあるんだ!
横幅100%でもボーダーや余白があると親要素をはみ出します。ボーダーや余白はwidthの外側にある為、その分要素自体が大きくなり、親要素をはみ出すことになってしまうのです。
この解説のポイントは下記になります。
- 横幅100%なのに親要素をはみ出す原因と対処法
- box-sizingの使い方
ひとつずつわかりやすく解説していくよ!
横幅100%なのに親要素をはみ出す原因
親要素をはみ出す例
子要素のwidthが100%の場合、その要素は親要素と同じ横幅になります。
ところが、この子要素にボーダーや余白が設定されていると、親要素をはみ出してしまう現象が起こります。
コードではみ出すところを見てみよう
実際にコーディングしたものを確認してみましょう。
<div id="demo_110-1">親要素
<div id="demo_110-2">子要素</div>
</div>
#demo_110-1{
width: 250px;
height: 100px;
background-color: blue;
color:white;
}
#demo_110-2{
width: 100%;
height: 50px;
padding: 5px;
background-color: tomato;
}
子要素のwidthに100%を設定していますが、親要素をはみ出しているのが確認出来ます。
親要素をはみ出す原因
なぜこのようなことが起こるのかというと、「要素の横幅にボーダーや余白が含まれていない」からです。
まずは下記の図を見てください。
この図は、CSSのwidthやborder, paddeling, marginなどの関係を表したものです。(※この概念をボックスモデルと呼びます。)
これを見るとわかるように、横幅(width)にはボーダー(border)や余白(paddingやmargin)が含まれません。
横幅(width)の外側に、ボーダー(border)や余白(paddingやmargin)が追加されるので、全体の大きさは指定した横幅(width)よりも大きくなってしまうんです。
横幅と余白、ボーダーの関係
例えば、widthが500pxのボックスがあるとして、なにもしなければボックスの横幅は500pxのですが、padingを左右に10pxずつ設定すればその分ボックスが20px広がり、全体としては520pxの横幅に広がります。
さらに、ボーダーが左右に10pxずつあれば、トータルでは540pxの大きさになってしまいます。
ちなみにマージンやパディング、ボックスモデルについて基本的な説明は下記の記事で解説しているので参考にしてください。
横幅100%の子要素の場合
同じように、横幅100%でも余白やボーダーが設定されていると親要素をはみ出してしまいます。
なぜなら横幅(width)100%の設定によって、子要素の横幅は親要素と同じになりますが、その外側にボーダーや余白が追加される為、全体で見ると親要素より大きくなってしまうからです。
要するにボーダーや余白の分、要素トータルのサイズは大きくなるんだ!
親要素をはみ出す場合の対処法
なるほど!そういうことだったのか…
解ってしまうと単純だよね!対処法も簡単だから覚えておこう!
親要素をはみ出す現象を解決する方法としては、CSSの「box-sizing」プロパティを使う方法がシンプルで簡単です。
box-sizingプロパティとは
box-sizingは、「どこまでを横幅・高さとするか」という解釈を変更できるプロパティです。これを変える事で、「横幅や高さにボーダーと余白(padding)を含める」ように変更する事ができます。
以下のようにして使います。
box-sizing: 値;
box-sizingの値
box-sizingの値は以下のいずれかを指定します。
- content-box;
- デフォルト値。横幅・高さに余白やボーダーを含めない
- border-box;
- 横幅・高さに余白(padding)やボーダーを含める
- inherit;
- 親要素の値を引き継ぐ
box-sizingの各値についての解説は後ほどじっくりしますが、まずは「どういう理屈ではみ出さなくなるのか」を解説していきます。
横幅や高さにborderやpaddingを含む事ができる
box-sizingの値を「border-box」に変更すると、「横幅・高さにborderやpaddingを含める」という解釈に変えることができます。
例えばどうなるのかというと、widthが500pxの要素であれば、borderやpaddingを設定してもトータルの大きさは500pxのまま変わることはありません。
横幅(width)の内側にボーダーや余白が入るイメージだよ!
marginについて
※marginに関しては、横幅・高さには含まれるようにする方法はありません。むしろ、marginは「外側の余白」なので、横幅・高さに含まれるようになると、要素の外側に余白が取れなくなってしまい逆に困ってしまいますね。
親要素をはみ出す現象を解決してみよう
横幅100%なのに親要素をはみ出してしまう現象は、box-sizingを「 border-box」に変更するだけで解決出来ます。
実際にコードでもみてみよう
実際にコーデでもどうなるかみてみましょう。
<div id="demo_110-3">親要素
<div id="demo_110-4">子要素</div>
</div>
#demo_110-3{
width: 250px;
height: 100px;
background-color: blue;
color:white;
}
#demo_110-4{
box-sizing:border-box;
width: 100%;
height: 50px;
padding: 5px;
background-color: tomato;
}
box-sizing:border-box;を追記しただけですが、はみ出さなくなりましたね!borderやpaddingが、widthに含まれるようになった為、親要素と同じ横幅になっているんですね。
box-sizingプロパティの解説詳細
box-sizingの値について解説していきます。
box-sizing:content-boxの詳細
「content-box」はデフォルト値です。何も指定しなければこの値になります。指定する場合は下記のように記述します。
box-sizing: content-box;
この値にすると、widthとheightにpaddingとborderは含まれないという解釈になります。
content-boxの問題点
上述したようにcontent-boxには、borderやpaddingを使うと思いがけず親要素をはみ出してしまうという問題点があります。
この原因は、「width、border、padding」の合計が100%を超えてしまっているから起こります。合計が100%を超えると、親要素より子要素が大きくなるのではみ出してしまうことになります。
「だったら100%になるように設定すればいいんじゃないの?例えば、width80%, padding10%, border10%みたいな…」
そのように考える方もいるかもしれませんが、その方法は実は使えません。というのもborderの太さは「%」を使うことができないという仕様があるからです。
borderに%は使えない!?
ボックスの最終的な大きさは「横幅(width)、ボーダー(border)、余白(padding、margin)」の合計ですが、ボーダーはpx指定しかできないため、
- 横幅80%
- パディング10%
- ボーダー5px
という風に、ボーダーだけpx指定をすることになります。これでは「width、border、padding」の合計をぴったり100%にすることができないため、はみ出してしまったり、逆に不要な余白ができてしまうことになるんです。
レスポンシブデザインのように横幅100%を多用するサイトでは、content-boxのままではとてもコーディングしづらいので、次に紹介するborder-boxに変えて制作することが多いです。
borderには%が使えないから、widthに%を使いたい場合は、borderが使いづらくなるんだ!
box-sizing:border-boxの詳細
下記のようにして指定します。
box-sizing:border-box;
border-boxを使うと、widthとheightにpaddingとborderが含まれるようになります。
例えば、widthが500pxのボックスにborder10px、paddingを10pxとすると、ボックスの横幅はかわらず内側にborderとpaddingが適用されます。
このように横幅・高さにpaddingとborderが含まれるようになるため、widthに100%を設定してしまえば、あとはどんなpaddingとborderを取っても、親要素をはみ出すことがなくなりレイアウト崩れを気にせず使う事ができます。
box-sizing:inheritの詳細
inheritとすると親の要素の設定を引き継ぎます。
box-sizing:inherit;
box-sizingのブラウザ対応状況
box-sizingはCSS3から登場した比較的新しいプロパティですが、ほとんど全てのブラウザが対応しています。
何も気にせず使ってしまっても問題ありません。
box-sizingを全要素に適用する方法
border-boxは使い勝手が良くレスポンシブデザインと相性が良いため、最近のサイト制作では全ての要素にborder-boxを適用する事が増えてきました。
一部の要素だけborder-boxに変えると、サイト内で横幅の解釈が変わりややこしくなるため、全てを統一した方が便利です。
全要素にスタイルを適用するには、全ての要素を指定する「*」(アスタリスク)を使います。擬似要素にも適用するため下記のように書くと良いでしょう。
*, *:before, *:after {
box-sizing: border-box;
}
まとめ
- 横幅100%でも、ボーダーや余白を設定すると親要素をはみ出
- デフォルトでは横幅や高さにボーダーや余白が含まれず、ボーダーや余白の分要素が大きくなるため、親要素をはみ出す
- box-sizingは、「どこまでを横幅・高さとするか」という解釈を変更できるプロパティ
- box-sizingを「border-box」にすると「横幅・高さにボーダーと余白(padding)を含める」ように変更する事ができるので、余白やボーダーを設定しても、親要素をはみ出さなくできる