Skip to content
This page has been auto-translated and may contain errors.View in English

ボックスモデル

docs.scrimba.com

CSSで物を配置し始めると、誰もが同じパズルに直面します。幅を設定してパディングを追加すると、要素が頼んだより広くなります。2つの段落が数字が示すより近くに置かれます。これはバグではありません。これはボックスモデルであり、すべての要素がどれだけのスペースを占有するかを決定するルールのセットです。一度それを視覚化できれば、ほとんどの配置に関する驚きは驚きではなくなります。

すべての要素がボックスです

CSSはページ上のすべての要素を、単語やリンクであっても長方形として扱います。その長方形は内側から外側へスタックされた4つのレイヤーで構成されており、これが**ボックスモデル**です。中央のコンテンツ、その周りのパディング、ボーダー、そして外側のマージンです。

壁に掛かった枠付き写真を想像してください。写真がコンテンツです。写真の周りの白いマット板がパディングで、枠の内側の余白です。木製のフレームがボーダーです。このフレームと次のフレームの間の空いた壁がマージンです。スタイルするすべての要素は同じように、内側から外側へパッケージされています。

css
.card {
  padding: 16px;              /* 内側のスペース、コンテンツの周り */
  border: 2px solid #333;     /* フレーム */
  margin: 24px;               /* 外側のスペース、隣同士の要素を遠ざける */
}

ブラウザがレンダリングするすべての要素は長方形のボックスであり、そのボックスは中心から外側に向かって測定された4つの部分を持ちます。コンテンツボックス(テキストまたは画像が配置されるところ)、パディング、ボーダー、マージンです。このアイデアはCSSの仕組みですでに見ました。ボックスモデルはサイズと配置を制御する部分です。

順序は重要です。各レイヤーはその前のレイヤーをラップするためです。パディングはコンテンツとボーダーの間にあるため、背景色はコンテンツとパディングを塗りつぶしますが、ボーダーの外側で止まります。マージンはボーダーの外側にあり、常に透明です。そのため、マージンに色を付けることはできません。

css
.card {
  padding: 16px;              /* ボーダーの内側、背景と共に表示される */
  border: 2px solid #333;
  margin: 24px;              /* ボーダーの外側、常に透明 */
  background: #f4f4f4;       /* コンテンツ + パディングを塗りつぶし、ボーダーで止まる */
}

レンダリングされるすべての要素は、少なくとも1つの長方形の**ボックス**を生成し、ボックスモデルはその4つのネストされた領域の仕様です。内側から外側へ。コンテンツボックス(要素のテキスト、画像、または子ボックスを保持する領域)、パディングボックス(コンテンツプラスパディング、要素の背景をまだ持つ透明なスペース)、ボーダーボックス(パディングボックスプラスボーダー、見える端)、マージンボックス(ボーダーボックスプラスマージン、要素をその隣同士から分離する最も外側の透明領域)です。

このネストから外れる2つの結果は、後で人々を混乱させます。まず、背景はマージンボックスではなくパディングボックスを塗ります。そのため、パディングはクリック可能で色付けできる内側のスペースを与え、マージンはスタイルできない空の分離を与えます。次に、宣言する幅と高さは、デフォルトではボックス全体を説明しません。それはそれの1つの領域のみを説明し、どの領域であるかはbox-sizingに依存し、次のセクションで正確にします。

css
.card {
  padding: 16px;
  border: 2px solid #333;
  margin: 24px;
  background: #f4f4f4;       /* コンテンツ + パディングを塗ります、マージンは決してありません */
}
Junoすべての要素がボックスです すべての要素は、内側から外側へ4つのレイヤーを持つボックスです。コンテンツ、次にパディング、次にボーダー、次にマージンです。枠付き写真の画像が頭に残りました。写真、マット板、フレーム、次のフレームへの隙間です。その画像を頭に入れれば、この章の残りはそこから続きます。
Junoすべての要素がボックスです コンテンツ、パディング、ボーダー、マージン。外側へラップします。背景はコンテンツとパディングを満たし、ボーダーで止まり、マージンは常に透明です。そのため、marginは色を取りません。ネストをまっすぐに保つと、配置ルールは恣意的に感じるのを止めます。
Junoすべての要素がボックスです 4つのネストされた領域。コンテンツボックス、パディングボックス、ボーダーボックス、マージンボックス。背景はボーダーボックスまで塗りますが、決してマージンではありません。そのため、パディングは色付け可能な内側で、マージンは空の分離です。宣言したwidthはこれらの領域の1つのみをサイズします。これが次のbox-sizingに関するセクションが存在する全理由です。

padding、border、margin

3つの配置レイヤーはそれぞれ1つの仕事をします。**パディング**はコンテンツとボーダーの間の内側のスペースです。マージンは外側のスペースで、他の要素を遠ざけます。ボーダーはそれらの間に引かれた線です。

4つの辺すべてに対して1つの値を設定するか、単一の辺をターゲットにできます。

css
.card {
  padding: 20px;             /* 4つの辺すべてが20px */
  margin-bottom: 32px;       /* 下の辺のみ */
}

ショートハンドpadding: 20pxは、上、右、下、左をすべて一緒に言う簡単な方法です。残りと異なるサイドが必要な場合は、margin-bottomのような特定のプロパティに到達してください。

**パディング**はボーダー内の内側のスペース、マージンはその外側のスペース、そしてボーダーはそれらの間の端です。保つべきルールは、マージンは隣同士を遠ざけ、パディングは要素の独自の内側を成長させます。 背景がテキストに対して窮屈に見える場合、それはパディングの仕事です。2つの要素が近すぎる場合、それはマージンの仕事です。

それぞれは、上から時計回りにサイドを埋めるショートハンドを取ります。1つの値はすべての4つの辺に適用され、2つの値は垂直次に水平を設定し、4つの値は上、右、下、左に行きます。

css
.hero {
  padding: 40px 24px;        /* 上下40px、左右24px */
  margin: 0 auto;            /* 垂直マージンなし、中央に配置するために自動左右 */
}

.card {
  padding-left: 16px;        /* サイドごと。1つのエッジのみが異なる場合 */
}

パディング、ボーダー、マージンは、同じギャップの3つの名前ではなく、3つの独立した配置制御で異なる動作をします。パディングはボーダー内の透明な領域であり、背景をまだ持ち、クリックに応答します。マージンはボーダー外の透明な領域で、要素をそのきょうだいから分離し、背景を持たない領域です。ボーダーは描画された端で、その幅に等しいレイアウトスペースも取ります。

3つすべてが時計回りのショートハンド(1、2、3、または4つの値が上/右/下/左に拡張される)を受け入れ、3つすべてサイドごとのロングハンドを持ちます。2つの動作は正確に保つ価値があります。マージンは負になる可能性があります。これは要素を隣同士の方向に引いたり乗ったりし、正当なレイアウトツールです。一方、パディングはゼロ以下にはなりません。そしてmargin: 0 autoは、要素が確定幅を持つ場合にのみ、ブロックを水平に中央に配置します。autoは余った水平スペースを分割することで解決し、ボックスがすでにそのコンテナを埋める場合、分割する余ったスペースはありません。

css
.hero {
  padding: 40px 24px;        /* 時計回りペア。垂直、水平 */
  margin: 0 auto;            /* .heroに設定幅でのみ中央に配置 */
  border-bottom: 1px solid #ddd;  /* ボーダーロングハンド、1つのエッジ、レイアウトの1px */
}

.card {
  margin-top: -8px;          /* 負のマージンはカードを上に引き上げます */
}
Junopadding、border、margin パディングはボーダー内の内側のスペース、マージンはその外側のスペース、ボーダーはそれらの間の線です。テキストがボックス内で窮屈に感じられる場合はpaddingを使用し、2つのボックスが近すぎる場合はmarginを使用してください。padding: 20pxのような1つの値は4つの辺をすべてカバーするか、margin-bottomのような辺を名付けると1つのみが変わる必要があります。
Junopadding、border、margin パディングは要素の独自の内側を成長させ、マージンはその隣同士を遠ざけます。どちらが必要かを知ることは多くの推測を保存します。ショートハンドは上から時計回りに実行されます。すべてのサイドに1つの値、垂直次に水平に2つ。背景がテキストに密接にハグされている場合、マージンではなくパディングが必要です。
Junopadding、border、margin パディングは背景とクリックを持ち、マージンは透明な分離であり、ボーダーはその幅に等しい実レイアウトスペースを取ります。マージンは要素を一緒に引くために負になる可能性があります。パディングはできません。そしてmargin: 0 autoは確定幅を持つブロックのみを中央に配置します。autoには分割する余ったスペースがないためです。

box-sizing: content-box vs border-box

ほぼすべての人を捕まえる驚きです。カードをwidth: 300pxに設定してパディングを追加すると、カードはページで300ピクセルより広くなります。あなたは何も間違っていません。デフォルトでは、widthは中央のコンテンツのみを測定し、パディングとボーダーは上に追加されます。

幅を期待した方法で振る舞わせる1行の修正があります。box-sizing: border-boxを設定すれば、今入力する幅はボックスの完全な幅です。パディングとボーダーが含まれています。

css
.card {
  box-sizing: border-box;    /* 幅がパディングとボーダーを含む */
  width: 300px;
  padding: 20px;             /* カードは300pxのままで、340pxではない */
}

デフォルトではすべての要素はbox-sizing: content-boxを使用します。つまり、設定するwidthはコンテンツボックスのみに適用されます。パディングとボーダーはその外側に追加されるため、ページに実際に表示されるボックスは入力した数より広くなります。これは100個の吹き出したレイアウトの背後にある古典的なサイズ設定の落とし穴です。

数学を一度行えば、それは明確です。content-boxを使用すると、300px幅プラス各辺に20pxパディングプラス各辺に2pxボーダーが300 + 40 + 4 = 344pxでレンダリングされます。**border-box**に切り替えると、widthはボーダーボックスを意味するようになります。パディングとボーダーは内側から差し引かれるため、要素は正確に300pxで、コンテンツは収まるように縮小します。

css
.card {
  box-sizing: content-box;   /* デフォルト */
  width: 300px;
  padding: 20px;
  border: 2px solid #333;
  /* 実際にレンダリングされた幅: 300 + 20 + 20 + 2 + 2 = 344px */
}

これはほぼ常に必要な操作なので、標準的な操作はユニバーサルセレクタでグローバルに設定することです。そのため、すべての要素がオプトインします。

css
* {
  box-sizing: border-box;    /* 1つのルール、どこでも予測可能なサイズ設定 */
}

box-sizingは、widthheightがどの領域を測定するかを決定し、2つの値があります。初期値はcontent-boxです。widthはコンテンツボックスを設定し、パディングとボーダーはその幅外にレイアウトされるため、ボーダーボックスであるページ上の実際のフットプリントはwidth + padding-left + padding-right + border-left + border-rightです。代替案は**border-box**です。widthはボーダーボックスを直接設定し、ブラウザは内側からパディングとボーダーを減算し、コンテンツボックスを残されたもので縮小します。

算術は正確に述べる価値があります。これが全体の理由がプロパティが存在するためです。width: 300px; padding: 20px; border: 2pxを与えられた場合。

css
/* content-box(デフォルト): パディングとボーダーが上に追加 */
.card {
  box-sizing: content-box;
  width: 300px;
  padding: 20px;
  border: 2px solid #333;
  /* ボーダーボックス = 300 + 40 + 4 = 344px; コンテンツボックス = 300px */
}

/* border-box: パディングとボーダーは宣言幅を食べます */
.card {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid #333;
  /* ボーダーボックス = 300px; コンテンツボックス = 300 - 40 - 4 = 256px */
}

border-boxを推奨します。サイズ設定を合成可能にします。 理由は実用的です。border-boxを使用すると、width: 25%で宣言されたコラムセットは、追加するパディングに関係なく、コンテナの4分の1のままです。パディングはもはや外側のサイズを変更しないためです。その予測可能性は、ほぼユニバーサルなリセットが疑似要素を含むすべてに適用される理由です。そのため、何もサイレントにcontent-boxに戻りません。

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

1つの精度注。これはwidthheightのみを管理します。マージンはbox-sizingに関わらずボーダーボックスの外側に常にあるため、宣言されたサイズにはカウントされません。これは直接下のマージン折りたたみに接続されます。これらのボックスを確実にサイズするためにユニットが必要な場合、サイズ設定ユニットはパーセンテージ、rem、ビューポートユニットがどのように解決されるかをカバーしています。

Junobox-sizing: content-box vs border-box デフォルトでは、設定するwidthは中央のコンテンツのみを測定するため、パディングとボーダーはボックスを入力した数より大きくします。box-sizing: border-boxを設定すればそれを修正します。幅は完全なボックス、パディングとボーダーが含まれます。これは長い間私を悩ませたので、早めに覚えておく価値があります。
Junobox-sizing: content-box vs border-box デフォルトcontent-boxwidthがコンテンツのみをサイズするため、パディングとボーダーは実ボックスを聞きたいより広くします。20pxパディングと2pxボーダーを持つ300pxカードは実際に344pxでレンダリングされます。border-boxに切り替えて、幅はボックス全体を意味します。それが*にグローバルに設定する理由は、ほとんどのスタイルシートの最初の標準的なラインです。
Junobox-sizing: content-box vs border-boxcontent-boxは幅の外側にパディングとボーダーを追加するため、300pxボックスは344pxになります。border-boxは内側から減算し、300pxで保持します。box-sizingに到達してください。パディングがもはや外側のサイズを変更しない場合、パーセンテージ幅は合成可能なままだからです。疑似要素と一緒に*に適用して、何もサイレントにデフォルトに戻りません。

マージン折りたたみ

もう1つの驚き。マージンをスタックすることについてです。2つの段落を上に置いて、最初に24px下マージンを与え、2番目に16px上マージンを与えると、それらの間に40pxのギャップを期待するかもしれません。実際に24pxを取得します。

これは**マージン折りたたみ**と呼ばれます。2つの垂直マージンが出会うとき、ブラウザはそれらを一緒に追加しません。それは2つのうち大きい方を保持し、小さい方を捨てます。そのため、より大きいマージンが勝ち、ギャップは24pxで、40pxではありません。上下のマージンのみで発生し、パディングとは決してありません。

css
.intro {
  margin-bottom: 24px;
}
.details {
  margin-top: 16px;
  /* それらの間のギャップは24px、より大きいマージン、40pxではない */
}

1つのブロックの下マージンが次の上マージンに出会うと、2つは合計されません。それらはより大きい2つに等しい単一のマージンに折りたたまれます。1つの段落にmargin-bottom: 24pxと次にmargin-top: 16pxを与えると、それらの間のスペースは24pxで、40pxではありません。これは**マージン折りたたみ**で、垂直マージンのみに影響します。

それを知る理由は、スペーシングについてどのように推論するかを変更するためです。ギャップが2つの数字が示唆するより小さい場合、あなたはおそらく折りたたみを見ていて、小さいマージンに追加することはそれが大きい方をに越すまで何もしません。垂直リズムを制御するクリーンな方法は、1つの方向のみでマージンを設定することです。たとえば、すべてのブロックのmargin-bottommargin-topなしなので、折りたたみは解決するものがありません。

css
.article > * {
  margin-top: 0;
  margin-bottom: 24px;       /* 1つの方向、ギャップは予測可能 */
}

**マージン折りたたみ**は、隣接する垂直マージンが通常フロー内で1つにマージされるルールです。サイズは2つのうち大きい方です(または最もポジティブ。ネガティブは最大の正と最もネガティブの合計によって処理されます)。通常フローはフレックス、グリッド、フロートが変更する前のブロックボックスのデフォルト上から下へのスタッキングです。.intro24px下マージンと.details16px上マージンを与えると、ギャップは24pxです。ブラウザは両方を単一の折りたたまれたマージンに解決するためです。

正確な部分は、何が折りたたまれ、折りたたまれないかを知ることです。エスケープは驚きを止める方法です。

  • 垂直マージンのみに影響します。水平マージンは決して折りたたまれません。2つの並列要素は常にそれらの対面マージンを追加します。
  • 2つのマージンの間の何かが折りたたみを止めます。ボーダー、任意のパディング、または子と独自の間の親のコンテンツ。
  • マージンはフォーマットコンテキスト境界を越えて折りたたまれません。フレックスまたはグリッドコンテナがその子に1つを確立するため、その内部のアイテムはマージンを決して折りたたみません。これは現代的なレイアウトがフロート時代のものより予測可能に感じる理由の1つです。
  • 親と最初または最後の子は何も分離されていない場合、それぞれを通して折りたためます。そのため、子の上マージンは予期せず親の外側に表示される可能性があります。padding-topまたはボーダーを親に追加することでそれを停止します。
css
/* 折りたたみが発生します。通常フロー内の隣接するきょうだい */
.intro { margin-bottom: 24px; }
.details { margin-top: 16px; }   /* ギャップは24pxで解決 */

/* 折りたたみ停止。マージンの間のボーダー */
.section {
  border-top: 1px solid #eee;    /* これで両方のマージンが適用され、マージなし */
}
Junoマージン折りたたみ 下マージンが上マージンに出会うとき、ブラウザは大きいものを保持し、小さいものを落とします。それらを追加する代わりに。そのため、下に24pxが上に16pxをに出会って24pxギャップを与え、40pxではありません。上下のマージンのみで発生し、最初は誰もが驚きます。
Junoマージン折りたたみ ブロック間の垂直マージンは2つの合計ではなく、大きい方に折りたたまれるため、ギャップは数字が示唆するより小さい場合があります。その場合、小さいマージンを成長させることはそれが大きい方をに越すまで何もしません。すべてのブロックにmargin-bottomのような1つの方向のみマージンを設定すると、全体をサイドステップします。
Junoマージン折りたたみ 通常フロー内の隣接する垂直マージンは大きい値にマージされ、水平マージンは決してしません。それらの間のボーダーまたはパディングが折りたたみを停止し、フレックスとグリッドコンテナはそれを完全に停止します。新しいフォーマットコンテキストを作成するため。親と最初の子のケースを見守ります。子の上マージンが親をエスケープします。padding-topまたはボーダーを追加して、親を保持するまで。