この記事は、http://css-tricks.com/ の Chris Coyier の許可を得て、一部変更し、翻訳しています。オリジナルの記事はここよりご覧いただけます。

もしかしたら何度も申し上げているかもしれませんが、WEBデザイン上の全ての要素は矩形のボックスです。私は本当の意味でこれが分かった時、初めてCSSベースのWEBデザインというものをしっかりと理解出来るようになり、また自分で表現したいレイアウトを実現出来るようになりました。今までにもボックスのポジショニングに関しては少しお話してきたかと思います。

しかし何気にボックスそれ自体に関しては、あまりお話していませんでしたよね。ボックスのサイズと言うのはどのように計算されているかご存知ですか?ボックス構成は以下の図で表すことが出来ます(黄色の部分がボックスで、点線部分はコンテンツです。):

thebox CSSボックスモデル

もしFirebugをお使いでしたら、これは見慣れた図ですよね。このFirebugの図は、どの数字がどのようにボックスに影響を与えるのかをよく表していると思います:

firebox jp CSSボックスモデル

1つ目の例でも2つ目の例でも、マージン部分は白で表されていることに注目してください。マージンはボックスのサイズには影響を与えません。けれども、ボックスの周りにある他のコンテンツに対しては影響を与えます。そのためCSSボックスモデルの使い方を理解することは大切になってきます。
ボックスのサイズは以下のような方法で算出されます:

Width(幅) width + padding-left + padding-right + border-left + border-right
Height(高さ) height + padding-top + padding-bottom + border-top + border-bottom

これらの要素が宣言されなかった場合は?

パディングやボーダーが宣言されなかった場合は、ゼロ(CSSリセットを使った場合が殆ど)か、ブラウザのデフォルト値(フォーム要素はリセットされないことが多いので、ゼロではない可能性の方が高い)になります。
ボックスの幅(width)が宣言されなかった場合(しかもボックスがブロック・レベル・エレメントだった場合)には、少し面倒くさいことになってきます。まずはここからお話して、後ほどそれ以外のことについてもお勉強しましょうか。

ブロック・レベル ボックスのデフォルト幅は?

もしボックス幅を指定をせず、またボックスのポジション設定がstaticかrelativeだった場合、ボックス幅自体は100%のままです。そしてパディングとボーダーは外側に付け加えられるのではなく、ボックスの内側を削っていきます。けれども、もし明示的にボックス幅を100%と指定した場合には、パディングは通常通り外側に設置されます。

weird 1 jp CSSボックスモデル

ここで学べることは、ボックスのデフォルト幅というのは厳密に言うと100%ではなく、「(いろいろ差し引いて)残ったもの」と言う感じです。ボックス幅を指定するかしないかによっていろいろと状況も変わってくるので、覚えておいて絶対に損はないです。
いつも頭を抱えてしまうのが、テキストエリアです。テキストエリアではcols属性は必須です。このcols属性を満足させる為に幅指定もした方が無難です。そして子要素を持つことは出来ません。その為、テキストエリアを使用する場合には、明示的に100%の幅指定をして、同様にパディングも設定しておけば、充分なエリアを確保出来るはずです。静的に設定された幅の環境ではピクセル幅に頼ることもしばしばありますが、流動的な幅設定の環境ではそれがうまく行くとは限りません。

絶対配置あり、幅指定なしの場合

ポジション設定がabsoluteで幅指定は無しのabs width jp CSSボックスモデル

場合はこれまたやっかいな動きを見せてくれます。この場合の幅とは、コンテンツを含有するために充分なエリアに過ぎません。従ってもしボックス内のコンテンツが単語1つだった場合には、その単語を表示するのに必要なエリアが「幅」となります。もし2つの単語だったら、その分幅が広がります。

text render abs jp CSSボックスモデル

ボックスの横幅は親要素(relative設定された直近の親要素か、ブラウザ ウインドウ)の100%に達するまでは広がり続け、100%に達したら回り込みを始めます。コンテンツを含有するために、ボックスが垂直方向に自動拡張することには疑問を感じないのに、同じことが垂直方向で起こると変な感じがしますね。テキストはプラットフォーム間で異なる方法でレンダリングされるということは言うまでもありませんが、それぞれのブラウザによって対応方法にクセがあるので、奇妙に感じる気持ちは否定しなくていいと思いますよ。

幅指定なしでfloat設定されている場合

幅指定なしで、float設定されたボックスも同じような動きを見せます。ボックス幅はコンテンツを含有するのに必要な分だけです。そして親要素(今度はrelative設定されている必要はありません)の幅に達するまで広がります。幅指定されていないボックスというのは非常に壊れやすいので、ページ全体のレイアウトのようにミッションクリティカルなシナリオなどでは依存しない方がよいでしょう。もしサイドバーとして使用するために、コラムをfloat指定して、必要幅を確保するために画像などの要素を内部に組み込んだりしてみた暁には、見事にトラブルにぶち当たります。

インライン要素だってボックスです

今まではボックスレベルの要素についてお話してきました。ボックスレベルの要素ならボックスとして考えるのも簡単かと思いますが、インライン要素だってボックスなんです。とてもとても細長い矩形を思い浮かべてみてください。その細長い矩形が各行を包み込んでいます。インライン要素でもその他のボックスのように、マージンやパディングやボーダーを設定することが出来るのです。

span jp CSSボックスモデル

この「包み込み」がとても紛らわしくて、上記のように一見左側のマージンはボックス全体を右側に押しやるのではないかと思いますが、実際は一行目のみです。何故ならボックスの開始場所はそこのみだからです。パディングは今まで同様各行の上部と下部に適用されます。上の行と下の行のパディングが重なり合った場合は無視され、本来必要な高さのみ維持されます。背景は動作を確認し易いように、透き通らせています。

自分の目で確認してみましょう

実際にページ上でボックスがどのようになっているのか見てみたいと思いませんか?スタイルシートに以下のコードを書き込んでみてください。

* {
   border: 1px solid red !important;
}