CSSのボックスモデルについて
CSSのボックスモデルについてちゃんと勉強したことなかったので、まとめてみました。
ボックスの種類
CSSにはボックスという概念があります。
これに沿って、CSS でレイアウトを作成したりアイテム同士を揃えたりするっていう話ですね。
- ブロックボックス
- インラインボックス
の2種類があり、これはCSSの display
プロパティ の値によって決まります。(inline-blockは後述 *1)
- 主なブロック要素(デフォルト
display: block;
)
<address>、<blockquote>、<div>、<dl>、<fieldset>、<form>、<h1>、
<hr>、<ol>、<p>、<pre>、<table>、<ul>
- 主なインライン要素(デフォルト
display: inlineblock;
)
<a>、<b>、<br>、<code>、<em>、<i>、<img>、<input>、<label>、<s>、<select>、
<span>、<strong>、<textarea>
ボックスモデルの定義
2種類はそれぞれ以下のように定義されている。
ブロックボックス
- 横幅と高さの指定: 適用される
- 横幅の初期値: 親要素と同じ
- 高さの初期値: 中身によって異なる(子になる要素に寄るということ)
- 他の要素との並び: ボックスは改行される(縦に並ぶ)
- margin、paddingが指定できる
インラインボックス
- 横幅と高さの指定: 適用されない(img や inputのように CSS で幅や高さを設定できる要素も有り)
- 横幅の初期値: 親要素と同じ
- 高さの初期値: 中身によって異なる
- 他の要素との並び: ボックスは改行されない(横に並ぶ)
- 上下の marginを指定できない
また、ボックスモデルには外側と内側の表示タイプがあります。
ブロックボックス、インラインボックスは外側の表示タイプということになり、それぞれのルールが適用されます。しかし、内部の表示タイプというものもあります。これは内部の値を決めることにより、内部表示タイプを変更し、決めた値に寄るルールを適用します。つまり、ブロックボックスであるブロック要素にdisplay: flex;
や display: grid;
を指定することにより、外側の表示タイプはブロックだけど、内部表示タイプはそれぞれ、flex
、grid
となるということです。CSSを書いた方ならわかると思いますが、もちろん内部表示タイプのルールがボックス内の要素のレイアウト方法に適用されます。
ボックスモデルとは
ボックスモデルについて理解するには、ボックスの構成を理解する必要があります。
以下の図のようにボックスは4つの要素で構成されています。
- マージンボックス
- ボーダーボックス
- パディングボックス
- コンテンツボックス
それぞれの構成する命名がそのまま適用可能なプロパティを表していますね。マージンボックスはボックスの一番外側の余白の領域で、 margin プロパティで指定できます。ボーダーボックスはpaddingの外側でmarginの内側に存在します、border-width プロパティで指定できます。パディンングボックスはcontent と border の間にある余白の領域です、いわゆる要素の内側の余白ですね。 padding プロパティで指定できます。最後にコンテンツボックスは textやimageといった要素そのものが表示されるところですね。 width と heightプロパティで指定できます。
ボックスのサイズは上記4つのボックスの領域を含めたものになります。なので縦幅、横幅共に「コンテンツ + パディング + ボーダー + マージン」の合計値となります。
ボックスモデルのサイズを計算する
なぜサイズ計算を行うのかというと、親要素からはみ出すという現象を回避したいからですね。例えば、ボックスのサイズがあらかじめ決まっており、特定のwidthを指定したい場合は、パディング + ボーダー + マージンの値をサイズからひき、調整し決定します。がこの方法だといちいち計算しないといけません。calc()
を用いることでこの計算から逃れることもできますが、calc()
は指定方法に癖があるので慣れが必要かもしれないですね。MDNのバナーの例がわかりやすいです。
(参考: https://developer.mozilla.org/ja/docs/Web/CSS/calc())
ボックス領域の指定
個人的に一番理解していなかったのはborder-sizingプロパティです。このプロパティを使うことで width、height で指定できるボックス領域のサイズを変更することができます。
border-sizing: border-box;
この指定の場合 marginを除く、コンテンツ + パディング + ボーダー のボックスの領域においてwidthとheightを指定できます。
border-sizing: padding-box;
コンテンツ + パディング のボックスの領域においてwidthとheightを指定できます。
border-sizing: content-box;
コンテンツボックスの領域においてwidthとheightを指定できます。
コンテンツ + パディング + ボーダー のボックスの領域においてwidthとheightを指定できたほうがCSSでレイアウトを作成する際、とても簡単になるのがわかると思います。なので基本的には全ての要素にはborder-sizing: border-box;
を指定したいとなります。reset css *2 にborder-sizing: border-box;
が指定されている場合が多いのはこの理由からですかね。(HTML5 Doctor Reset CSSとかにはないですが...)
*1 display: inline-block;
このプロパティを設定すると、インラインブロックボックスの定義するルールが適用されます。
- 他の要素との並び: ボックスは改行されない
- 横幅と高さの指定: 適用される
- margin、paddingが指定できる
といったブロックボックスとインラインボックスの特徴を有します。メニューバーやブログサイトにあるソーシャルリンクの横並び配置のやつといった横に要素を並べる時、便利ですね。
*2 reset css
様々なブラウザを使ったとしても同じようにWeb Applicationが表示されるためのCSSファイルのことです。ブラウザが元々持っているデフォルトのCSSの設定を上書きし、各種ブラウザ間の表示を揃えるという仕組みです。ブラウザ毎に異なるスタイルを持つので、特定のセレクタに対してプロパティを指定して打ち消すといったことをしています。
Discussion