The Box Model: Understanding Layout
The box model is the sizing system behind every element on a web page. A heading, paragraph, image, button, form input, list item, card, and layout container are all treated as rectangular boxes.
If you understand the box model, layout bugs become easier to reason about because you can answer three practical questions:
- How wide or tall is this element?
- How much space is inside the element?
- How much space is outside the element?
1. Every Element Is a Box
Browsers paint elements as rectangles. Even text appears inside an invisible rectangular area.
<article class="card">
<h2>CSS Box Model</h2>
<p>Every element occupies a rectangle.</p>
</article>
.card {
width: 320px;
padding: 24px;
border: 2px solid #94a3b8;
margin: 32px;
}
2. The Four Layers of the Box
Each element has four layers:
- Content: text, images, child elements, or other actual content.
- Padding: transparent space inside the border.
- Border: the visible or invisible edge around padding and content.
- Margin: transparent space outside the border that separates this box from other boxes.
The easiest way to remember the layers is:
outside -> margin -> border -> padding -> content <- inside
3. Content, Padding, Border, and Margin in Code
.box {
width: 300px;
height: 160px;
padding: 24px;
border: 4px solid #0f172a;
margin: 32px;
}
Each property affects a different layer.
| Property | Affects | Visual result |
|---|---|---|
width / height | Content box by default | Sets content area size |
padding | Inside border | Pushes content inward |
border | Box edge | Draws an edge |
margin | Outside border | Pushes neighboring boxes away |
Margins do not receive background color. Padding does.
.notice {
background: #fef3c7;
padding: 1rem;
margin: 1rem 0;
}
The yellow background fills the content and padding areas, but not the margin.
4. The Width Calculation Trap
By default, CSS uses box-sizing: content-box.
That means:
total visible width = width + left padding + right padding + left border + right border
Example:
.card {
width: 300px;
padding: 20px;
border: 5px solid black;
margin: 30px;
}
The visible box becomes:
300 + 20 + 20 + 5 + 5 = 350px
The margins are outside that visible width, so the element occupies even more space in layout.
This default can surprise beginners because width: 300px does not always mean the final visible element is 300px wide.
5. The Modern Fix: box-sizing: border-box
Most projects use this reset:
*,
*::before,
*::after {
box-sizing: border-box;
}
With border-box, the declared width includes content, padding, and border.
.card {
width: 300px;
padding: 20px;
border: 5px solid black;
box-sizing: border-box;
}
The final visible width stays 300px. The content area shrinks to make room for padding and border.
Use border-box unless you have a specific reason not to.
6. Padding vs. Margin
Use padding when the space belongs to the element. Use margin when the space belongs between elements.
.button {
padding: 0.75rem 1rem;
}
.card {
margin-bottom: 1.5rem;
}
Padding
Padding makes a component feel larger and more comfortable. It is part of the clickable area for buttons and links.
.tag {
padding: 0.25rem 0.625rem;
border-radius: 999px;
}
Margin
Margin separates siblings.
.article + .article {
margin-top: 2rem;
}
This selector adds margin only between articles, not before the first article.
7. Margin Collapsing
Vertical margins between block elements can collapse. If one element has margin-bottom: 24px and the next has margin-top: 16px, the space between them may be 24px, not 40px.
.first {
margin-bottom: 24px;
}
.second {
margin-top: 16px;
}
Margin collapsing commonly happens between:
- Adjacent vertical block margins.
- A parent and its first or last child.
- Empty block elements.
Margins do not collapse in many modern layout contexts, including flex and grid containers.
If collapsing creates confusing spacing, use one of these approaches:
- Use padding on a parent.
- Use flexbox or grid with
gap. - Use only one direction for margins, such as
margin-bottom.
8. gap: The Modern Spacing Tool
For flex and grid layouts, gap is often cleaner than margin.
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
gap belongs to the parent, so you avoid adding special margin rules to every child.
.toolbar {
display: flex;
gap: 0.75rem;
}
Use gap for spacing items in a layout. Use margin when an individual component needs external spacing in normal flow.
9. Centering with margin: auto
To horizontally center a block element:
.container {
width: min(100% - 2rem, 1200px);
margin-inline: auto;
}
The element needs a width smaller than its parent. Auto margins absorb the remaining space equally.
Classic version:
.centered-container {
max-width: 1200px;
margin: 0 auto;
}
Modern logical-property version:
.centered-container {
max-inline-size: 1200px;
margin-inline: auto;
}
Logical properties adapt better to different writing modes.
10. Border, Outline, and Border Radius
Border
border is part of the box model. It can affect layout size unless you use border-box.
.panel {
border: 1px solid #cbd5e1;
}
Outline
outline is drawn outside the element and does not take up layout space.
button:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 3px;
}
Use outlines for accessible focus states. Do not remove focus outlines unless you replace them with an equally visible focus style.
Border Radius
border-radius rounds corners.
.avatar {
width: 64px;
height: 64px;
border-radius: 50%;
}
50% turns a square into a circle.
11. Overflow
Content can be larger than its box. The overflow property controls what happens.
.preview {
width: 280px;
height: 120px;
overflow: auto;
}
Common values:
visible: content spills out.hidden: content is clipped.auto: scrollbars appear only when needed.scroll: scrollbars are always reserved.
For long text in a single line, use:
.breadcrumb-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
That creates the familiar ... truncation effect.
12. Display Types and the Box Model
Different display types behave differently.
| Display | Starts new line? | Width/height respected? | Example |
|---|---|---|---|
block | Yes | Yes | <div>, <p>, <section> |
inline | No | Not normally | <span>, <a> |
inline-block | No | Yes | badges, small controls |
flex | Yes by default | Yes | one-dimensional layouts |
grid | Yes by default | Yes | two-dimensional layouts |
.badge {
display: inline-block;
padding: 0.25rem 0.5rem;
}
inline-block is useful when you want an element to sit in text flow but still accept padding, width, and height reliably.
13. Practical Example: Balanced Card
.card {
width: min(100%, 420px);
margin-inline: auto;
padding: 1.5rem;
border: 1px solid #d6d3d1;
border-radius: 18px;
background: #fffdf8;
box-shadow: 0 16px 32px rgba(15, 23, 42, 0.08);
}
.card > * + * {
margin-top: 1rem;
}
<article class="card">
<h2>Box Model</h2>
<p>Padding creates internal breathing room.</p>
<a href="/courses/css">Continue lesson</a>
</article>
Why this works:
width: min(100%, 420px)keeps the card responsive.margin-inline: autocenters it.paddingcreates breathing room inside.borderdefines the edge.box-shadowcreates depth without changing layout..card > * + *spaces direct child elements without adding top margin to the first child.
14. Debugging Checklist
When a layout looks wrong, inspect the element and check:
- What is the computed
box-sizing? - Is
widthmeasuring content only or the full border box? - Is padding expanding the element?
- Is a border adding unexpected size?
- Are margins collapsing?
- Is
overflowclipping content? - Is the element
inline,block,flex, orgrid? - Would parent-level
gapbe cleaner than child margins?
15. Mini Practice
Build a card with these requirements:
- The card should never be wider than
420px. - It should be centered.
- It should have
24pxinternal spacing. - It should have a visible border.
- It should use
border-box. - It should clip long content with scrollbars if needed.
Possible answer:
.practice-card {
box-sizing: border-box;
width: min(100%, 420px);
margin-inline: auto;
padding: 24px;
border: 1px solid #cbd5e1;
border-radius: 16px;
overflow: auto;
}