次のHTMLコードがあるとします。
<p>I am a paragraph of text that has a few words in it.</p>
このHTMLに次のCSSを記述します。
p {
width: 100px;
height: 50px;
padding: 20px;
border: 1px solid;
}
コンテンツは要素から外れ、幅は100ピクセルではなく142ピクセルになります。なぜでしょうか。ボックスモデルはCSSの重要な基盤です。より予測可能なCSSを作成するには、ボックスモデルがどのように機能して、CSSの他の側面によってどのように影響を受けるのかを理解する必要があります。そして、重要な点は、ボックスモデルを制御する方法を理解することです。
CSSを作成するとき、またはWeb全般で作業するときに覚えておくべき非常に重要なことは、CSSによって表示される要素がすべてボックスであるということです。これは、border-radius
を使用して円のように見えるボックスでも、単純なテキストでも同じです。覚えておくべき重要なことは、それがすべてボックスであるということです。
コンテンツとサイズ設定
ボックスの動作は、 display
値、設定されたサイズ、およびボックス内に存在するコンテンツに基づいて異なります。このコンテンツは、子要素によって生成されたさらに多くのボックスであったり、プレーンテキストコンテンツであったりする可能性があります。いずれにしても、このコンテンツはデフォルトでボックスのサイズに影響します。
これを制御するには、外在サイズ設定を使用します。あるいは、内在サイズ設定を使用して、コンテンツサイズに基づいてブラウザに決定させることもできます。
デモを使用して、違いを簡単に見てみましょう。
デモでは、固定サイズで太い境界線のボックスがあり、このボックスに「CSS is awesome」という単語が入っています。このボックスは幅設定があるので、外在サイズです。これで子コンテンツのサイズが制御されます。ただし、これには問題があります。「awesome」という単語がボックスに対して大きすぎるため、親ボックスの境界ボックスの外側にオーバーフローしてしまいます(この点については授業の後半で詳しく説明します)。 このオーバーフローを防止するための方法の1つは、幅の設定を解除するか、この場合はwidth
をmin-content
に設定して、ボックスを内在サイズにできるようにすることです。 min-content
キーワードは、ボックスの幅をコンテンツの内在最小幅(「{awesome」)に制限するようにボックスに命令します。これにより、「CSS is awesome」がボックス内にきっちりと収まります。
さらに複雑な例を見て、実際のコンテンツに対するさまざまなサイズ設定の影響を確認しましょう。
内在サイズ設定のオンとオフを切り替え、外在サイズ設定をより詳細に制御し、コンテンツに内在サイズ設定をより詳細に制御させる方法を確認します。内在および外在サイズ設定の効果を確認するには、カードにコンテンツの文をいくつか追加します。この要素が外在サイズ設定を使用しているときには、追加できるコンテンツの量に制限があり、それを超えると要素の境界からオーバーフローしますが、内部サイズ設定がオンになっている場合はオーバーフローしません。
デフォルトでは、この要素にはwidth
とheight
があり、いずれも400px
に設定されています。これらのサイズは、要素内のすべてに厳密な境界を設定します。この境界は、コンテンツがボックスに対して大きすぎる場合を除いて尊重されます。大きすぎる場合、目に見えるオーバーフローが発生します。花の写真の下にあるキャプションの内容をボックスの高さ(2、3行)を超えるように変更すると、この実際の動作を確認できます。
内在サイズ設定に切り替えると、ボックスのコンテンツのサイズに基づいて、ブラウザに決定させます。内在サイズ設定では、ボックスがコンテンツのサイズ変更を試みるのではなく、コンテンツに合わせてボックスのサイズが変更されるため、オーバーフローが発生する可能性は大幅に低くなります。これはブラウザのデフォルトの柔軟な動作であることを覚えておくことが重要です。表面上は外在サイズ設定の方がより細かい制御ができますが、ほとんどの場合において内在サイズ設定が最も柔軟性に優れています。
ボックスモデルの領域
ボックスは、すべてが特定の仕事をする別個のボックスモデル領域で構成されています。
まず、コンテンツボックスから始めます。これはコンテンツが存在する領域です。すでに学習したように、このコンテンツは親のサイズを制御できるため、通常は、最もサイズが変動する領域です。
パディングボックスはコンテンツボックスを囲み、padding
プロパティによって作成されたスペースです。パディングはボックス内にあるため、ボックスの背景は作成されたスペースに表示されます。 overflow: auto
やoverflow: scroll
などのオーバーフロールールがボックスに設定されている場合、スクロールバーもこのスペースを占有します。
境界ボックスはパディングボックスを囲みます。スペースはborder
値によって占められます。境界ボックスはボックスの境界です。境界エッジは視覚的に見える内容の限界です。 border
プロパティは、要素を視覚的にフレーム化するために使用されます。
最後の領域であるマージンボックスはボックスの周囲のスペースであり、ボックスのmargin
ルールによって定義されます。 outline
やbox-shadow
などのプロパティも上部に描画されるためこのスペースを占め、ボックスのサイズには影響しません。 ボックスではoutline-width
を200px
に設定することができ、ボックスを含むボックスのすべての要素がまったく同じサイズになります。
役に立つ例
ボックスモデルは複雑で理解することが難しいので、例を使用して学習した内容をまとめます。
この図では、3つのフォトフレームが隣に並べて壁に取り付けられています。この図には、フレームの要素をボックスモデルに関連付けるラベルがあります。
この例を分解するには、次の手順を実行します。
- コンテンツボックスはアートワークです。
- パディングボックスは、フレームとアートワークの間にある白いマットです。
- ボーダーボックスはフレームであり、アートワークに文字通りのボーダーを提供します。
- マージンボックスは、各フレーム間のスペースです。
- 影はマージンボックスと同じスペースを占めます。
ボックスモデルのデバッグ
ブラウザのDevToolsは、選択したボックスのボックスモデル計算を視覚化します。これは、ボックスモデルがどのように機能するか、そして重要な点として作業中のWebサイトにどのように影響するかを理解するのに役立ちます。
先に進み、ブラウザで次の手順を試します。
- DevToolsを開く
- 要素を選択します
- ボックスモデルデバッガーを表示する
ボックスモデルの制御
ボックスモデルを制御する方法を理解するには、まずブラウザで発生する動作を理解する必要があります。
すべてのブラウザは、ユーザーエージェントスタイルシートをHTMLドキュメントに適用します。使用されるCSSはブラウザごとに異なりますが、コンテンツを読みやすくするために適切なデフォルト設定を提供します。これらは、CSSが定義されていない場合に、要素がどのように表示され、動作するかを定義します。 これは、ボックスのデフォルトのdisplay
も設定されている、ユーザーエージェントスタイルにあります。たとえば、通常のフローでは、 <div>
要素のデフォルトのdisplay
値はblock
であり、 <li>
のデフォルトのdisplay
値はlist-item
であり、 <span>
のデフォルトのdisplay
値はinline
です。
inline
要素にはブロックマージンがありますが、他の要素はそれを無視します。 inline-block
使用すると、これらの要素はブロックマージンを適用しますが、要素はinline
要素と同じ動作のほとんどを維持します。 block
アイテムは、デフォルトで使用可能なインラインスペースを埋めますが、 inline
要素とinline-block
要素はそのコンテンツと同じ大きさしかありません。
ユーザーエージェントのスタイルが各ボックスにどのように影響するかを理解するとともにbox-sizing
を理解する必要があります。これは、ボックスのサイズを計算する方法をボックスに指示します。デフォルトでは、すべての要素のユーザーエージェントスタイルは次のとおりです。box-sizing: content-box;
。
box-sizing
がcontent-box
の値であるということは、width
やheight
などのサイズを設定すると、それらがコンテンツボックスに適用されることを意味します。次に、 padding
とborder
を設定すると、これらの値がコンテンツボックスのサイズに追加されます。
Check your understanding
Test your knowledge of box model size impacting properties
.my-box { width: 200px; border: 10px solid; padding: 20px; }
How wide do you think .my-box
will be?
このボックスの実際の幅は260pxになります。 CSSはデフォルトのbox-sizing: content-box
ため、適用される幅はコンテンツの幅であり、 padding
とborder
がそれに追加されます。したがって、コンテンツの200px +パディングの40px +境界線の20pxは、合計で260pxの表示幅になります。
border-box
を使用するように次の変更を加えることで、これを制御できます。
.my-box {
box-sizing: border-box;
width: 200px;
border: 10px solid;
padding: 20px;
}
この代替ボックスモデルは、CSSにコンテンツボックスではなく境界ボックスにwidth
を適用するように命令します。つまり、 border
とpadding
が押し込まれます。その結果、 .my-box
を200px
幅に設定すると、実際には200px
幅でレンダリングされます。
次のインタラクティブデモでこれがどのように機能するかを確認してください。 box-sizing
値を切り替えると、青い背景で表示されます。CSSはボックス内に適用されています。
*,
*::before,
*::after {
box-sizing: border-box;
}
このCSSルールは、ドキュメント内のすべての要素と、すべての::before
および::after
疑似要素を選択し、 box-sizing: border-box
を適用します。これは、すべての要素にこの代替ボックスモデルがあることを意味します。
代替ボックスモデルでは予測可能性が高くなることがあるため、この例のように、開発者はこのルールをこのようなリセットやノーマライザーに追加することがよくあります。