📦 Lesson 12: The Box Model
Every single element on a web page — every heading, paragraph, image, link, and div — is a rectangular box. Even things that look round or irregular are boxes underneath. The CSS Box Model defines how these boxes are sized, spaced, and laid out. Once you understand it, you control the page.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Identify the four layers of the box model: content, padding, border, margin
- Use
padding,border, andmarginproperties to control spacing - Explain why
box-sizing: border-boxmakes sizing predictable - Use shorthand properties for padding, margin, and border
- Understand the difference between block and inline elements
- Inspect the box model visually using browser DevTools
- Apply spacing and borders to your project pages
Estimated Time: 50 minutes
Hands-on: You'll use DevTools to inspect boxes and add spacing to your site.
📑 In This Lesson
Everything Is a Box
This might be the single most important concept in CSS: every element is a rectangular box. A heading is a box. A paragraph is a box. An image is a box. A link inside a paragraph is a box. Even a single word wrapped in a <span> is a box.
You can prove it to yourself right now. Add this CSS to any page:
/* Temporary debug rule — shows every element's box */
* {
outline: 2px solid red;
}
The * selector targets every element, and outline draws a line around each box without affecting layout. Suddenly your page looks like a grid of nested rectangles — because that's exactly what it is.
The box model is the system that controls how big each box is and how much space it takes up. Master the box model, and layout stops being mysterious.
The Four Layers
Every box has four layers, from inside to outside:
(outer space — transparent)"] --> B["Border
(visible edge)"] B --> C["Padding
(inner space — shows background)"] C --> D["Content
(text, images, child elements)"] style A fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#1e293b style B fill:#fffbeb,stroke:#f59e0b,stroke-width:2px,color:#1e293b style C fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,color:#1e293b style D fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b
- Content — the actual stuff inside the element: text, an image, child elements. This is what
widthandheightcontrol (by default). - Padding — space between the content and the border. Padding is inside the box — the element's background color shows through it.
- Border — a visible (or invisible) line around the padding. You control its width, style, and color.
- Margin — space outside the border. Margin pushes other elements away. It's always transparent — the parent's background shows through.
Here's a concrete example. Imagine a box with these styles:
.card {
width: 300px;
padding: 20px;
border: 2px solid #3b82f6;
margin: 15px;
}
How much total horizontal space does this box occupy?
- Content: 300px
- Padding: 20px left + 20px right = 40px
- Border: 2px left + 2px right = 4px
- Margin: 15px left + 15px right = 30px
- Total: 300 + 40 + 4 + 30 = 374px
Wait — we set width: 300px but the box takes up 374px? That's the default behavior, and it trips up everyone. We'll fix it shortly with box-sizing.
💡 A Real-World Analogy
Think of the box model like a framed picture. The content is the photo itself. The padding is the matting around the photo. The border is the frame. The margin is the wall space between this frame and the next one.
Padding — Inner Breathing Room
Padding creates space inside the element, between the content and the border. The element's background color fills the padding area.
Individual Sides
.card {
padding-top: 20px;
padding-right: 30px;
padding-bottom: 20px;
padding-left: 30px;
}
Shorthand (Clockwise: Top, Right, Bottom, Left)
CSS padding shorthand follows the clock — Top, Right, Bottom, Left (think "TRouBLe"):
/* All four sides different: top right bottom left */
.card { padding: 10px 20px 15px 20px; }
/* Top/bottom and left/right: vertical horizontal */
.card { padding: 20px 30px; }
/* All four sides the same */
.card { padding: 20px; }
/* Top, left/right, bottom */
.card { padding: 10px 20px 15px; }
The two-value shorthand (padding: 20px 30px;) is the most commonly used — it sets 20px top and bottom, 30px left and right.
When to Use Padding
- Give text breathing room inside a colored box or card
- Space content away from the border
- Create clickable area around a link or button (bigger padding = easier to click)
/* A card with comfortable inner spacing */
.info-card {
background-color: #eff6ff;
padding: 20px 24px;
border-radius: 8px;
}
/* A button with generous click area */
.btn {
padding: 12px 24px;
background-color: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
Border — The Visible Edge
The border sits between padding and margin. It has three properties: width, style, and color.
The Border Shorthand
/* width style color — all in one line */
.card {
border: 2px solid #e2e8f0;
}
Border Styles
| Style | Appearance | Common Use |
|---|---|---|
solid |
A continuous line | Cards, containers, dividers |
dashed |
A series of dashes | Emphasis, selection areas |
dotted |
A series of dots | Decorative, light dividers |
double |
Two parallel lines | Formal, decorative |
none |
No border (default) | Removing inherited borders |
Individual Sides
/* Only a bottom border — great for section dividers */
h2 {
border-bottom: 2px solid #3b82f6;
padding-bottom: 8px;
}
/* Left accent border — common for quotes and callouts */
aside {
border-left: 4px solid #3b82f6;
padding-left: 16px;
}
/* Different borders on different sides */
.fancy-card {
border-top: 4px solid #6366f1;
border-bottom: 1px solid #e2e8f0;
border-left: none;
border-right: none;
}
Border Radius (Rounded Corners)
border-radius rounds the corners of an element's box — even if it has no visible border:
/* Slightly rounded corners */
.card {
border-radius: 8px;
}
/* Pill shape */
.tag {
border-radius: 999px;
padding: 4px 12px;
}
/* Circle (works on square elements) */
.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
}
/* Different radius per corner: top-left, top-right, bottom-right, bottom-left */
.modal {
border-radius: 12px 12px 0 0; /* rounded top, square bottom */
}
Margin — Outer Breathing Room
Margin creates space outside the element, pushing other elements away. Unlike padding, margin is always transparent — you can't see it directly.
Syntax (Same as Padding)
/* Individual sides */
.card {
margin-top: 20px;
margin-bottom: 20px;
}
/* Shorthand: top right bottom left */
.card { margin: 20px 0 20px 0; }
/* Shorthand: vertical horizontal */
.card { margin: 20px 0; }
/* All sides */
.card { margin: 20px; }
Centering with margin: auto
One of the most useful tricks in CSS — centering a block element horizontally:
.container {
width: 800px;
margin: 0 auto; /* 0 top/bottom, auto left/right */
}
auto tells the browser to split the remaining space equally between left and right margins, centering the element. This only works on block elements with a set width.
Margin Collapsing
Here's a quirk that surprises every beginner: when two vertical margins touch, they collapse into one. The larger margin wins; they don't add together.
h2 {
margin-bottom: 20px;
}
p {
margin-top: 16px;
}
You might expect 36px of space between the <h2> and the <p>. Instead, you get 20px — the larger of the two. This is called margin collapsing, and it only happens vertically (top/bottom), never horizontally (left/right).
margin-bottom: 20px"] --- B["Collapsed
Result: 20px
(larger wins)"] B --- C["p
margin-top: 16px"] style A fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b style B fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#1e293b style C fill:#eff6ff,stroke:#3b82f6,stroke-width:2px,color:#1e293b
💡 Margin vs. Padding Cheat Sheet
Padding = space inside the box (between content and border). Background color shows through. Use it when you want breathing room within an element.
Margin = space outside the box (between this element and neighbors). Always transparent. Use it to separate elements from each other.
Still unsure? Ask: "Do I want the background to extend through this space?" If yes → padding. If no → margin.
The box-sizing Fix
Remember the 300px-wide card that actually took up 374px? That's because the default box-sizing is content-box, where width only controls the content area — padding and border are added on top.
/* Default behavior (content-box) */
.card {
width: 300px;
padding: 20px;
border: 2px solid #ccc;
}
/* Actual width: 300 + 40 + 4 = 344px. Frustrating! */
The fix is box-sizing: border-box, which includes padding and border inside the specified width:
/* With border-box */
.card {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 2px solid #ccc;
}
/* Actual width: 300px. Content area shrinks to 256px to make room. */
Total = width + padding + border
300 + 40 + 4 = 344px"] C["border-box (recommended)"] --> D["width = content + padding + border
Total = width
300px = 300px"] style A fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#1e293b style B fill:#fef2f2,stroke:#ef4444,stroke-width:1px,color:#1e293b style C fill:#f0fdf4,stroke:#22c55e,stroke-width:2px,color:#1e293b style D fill:#f0fdf4,stroke:#22c55e,stroke-width:1px,color:#1e293b
Every modern CSS project starts with this universal reset:
/* Apply border-box to EVERYTHING */
*, *::before, *::after {
box-sizing: border-box;
}
This one rule eliminates the most common source of layout confusion in CSS. Put it at the very top of your stylesheet and never think about content-box again.
💡 Why Isn't border-box the Default?
Historical reasons. The original CSS spec chose content-box in the late 1990s. By the time everyone agreed border-box was better, billions of existing websites depended on the old behavior. Changing the default would break the web. So we apply the fix manually with the universal selector reset. It's one of those "always do this" patterns in CSS.
Block vs. Inline Elements
The box model behaves differently depending on whether an element is block-level or inline. This distinction affects how padding, margin, and width work.
Block Elements
Block elements take up the full available width and start on a new line. The box model works completely as expected:
<!-- Each of these starts on a new line -->
<h1>Heading</h1>
<p>Paragraph</p>
<div>Container</div>
<section>Section</section>
Common block elements: <div>, <p>, <h1>–<h6>, <section>, <article>, <header>, <footer>, <nav>, <main>, <ul>, <ol>, <li>, <form>.
Inline Elements
Inline elements flow within text on the same line. They only take up as much width as their content needs. Crucially, vertical padding and margin don't push other lines away:
<!-- These flow side by side within text -->
<p>This is <strong>bold</strong> and <em>italic</em> text
with a <a href="#">link</a> inside it.</p>
Common inline elements: <span>, <a>, <strong>, <em>, <code>, <img> (technically inline-replaced), <br>.
display: inline-block — The Best of Both
Sometimes you want an element that flows inline but respects the full box model (width, height, vertical padding/margin). That's inline-block:
.tag {
display: inline-block;
padding: 4px 12px;
background-color: #eff6ff;
border: 1px solid #bfdbfe;
border-radius: 999px;
font-size: 0.875rem;
}
<p>Topics: <span class="tag">HTML</span>
<span class="tag">CSS</span>
<span class="tag">Web Dev</span></p>
The tags sit side by side (inline behavior) but fully respect padding, margin, and width (block behavior).
| Behavior | block |
inline |
inline-block |
|---|---|---|---|
| Starts on new line? | Yes | No | No |
| Takes full width? | Yes | No (content width) | No (content width) |
| Width/height work? | Yes | No | Yes |
| Vertical padding/margin push? | Yes | No | Yes |
Inspecting the Box Model in DevTools
The browser's DevTools give you a visual representation of the box model for any element. This is the fastest way to debug spacing issues.
How to Inspect
- Right-click any element on your page and choose Inspect (or press F12)
- In the Elements panel, click on the element you want to examine
- Look at the Computed tab (or the box model diagram in the Styles panel)
- You'll see a nested rectangle diagram showing content, padding, border, and margin with exact pixel values
The diagram is color-coded:
- Blue — content area
- Green — padding
- Yellow/orange — border
- Orange/salmon — margin
When you hover over an element in DevTools, the page itself highlights these zones in the same colors. This makes it instantly obvious where space is coming from.
💡 Debugging Tip
When something isn't spaced the way you expect, don't guess — inspect it. Nine times out of ten, the DevTools box model diagram will show you exactly which layer (margin, padding, or border) is causing the unexpected spacing. It's the single most useful debugging tool for CSS layout.
Hands-on Exercise
🏋️ Exercise: Box Model Spacing
Objective: Add the box-sizing reset and apply professional spacing to your website.
Instructions:
- Add the universal
box-sizingreset at the top of yourcss/style.css:*, *::before, *::after { box-sizing: border-box; } - Set the
bodymargin to0(remove the browser default) - Create a
.containerclass withmax-width: 800px;andmargin: 0 auto;to center your page content, pluspadding: 0 20px;for side breathing room on small screens - Wrap your
<main>content in a<div class="container"> - Create a styled
.cardclass:- Background color: white or your
--color-bg-alt - Padding:
20px 24px - Border:
1px solidwith your border color variable - Border radius:
8px - Margin bottom:
20px
- Background color: white or your
- Wrap one section of your homepage content in a
<div class="card">to test it - Style the
<aside>with a left accent border, padding, and a subtle background - Open DevTools and inspect several elements — observe the box model diagram for each
💡 Hint
max-width is better than width for the container — it centers on large screens but allows the container to shrink on small screens instead of causing horizontal scroll. Combine it with margin: 0 auto; for centering and padding: 0 20px; so content never touches the screen edges on mobile.
✅ Example Solution
/* Add to the TOP of css/style.css */
/* ===========================
Reset & Box Sizing
=========================== */
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Inter", -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, sans-serif;
font-size: 1rem;
line-height: 1.6;
color: var(--color-text);
background-color: var(--color-bg);
}
/* ===========================
Layout
=========================== */
.container {
max-width: 800px;
margin: 0 auto;
padding: 0 20px;
}
/* ===========================
Cards
=========================== */
.card {
background-color: white;
padding: 20px 24px;
border: 1px solid var(--color-border);
border-radius: 8px;
margin-bottom: 20px;
}
.card-accent {
border-left: 4px solid var(--color-accent);
}
/* ===========================
Semantic Sections
=========================== */
header {
background-color: var(--color-primary);
color: white;
padding: 20px 0;
}
header .container {
/* The container inside the header centers the content */
}
aside {
background-color: var(--color-bg-alt);
border-left: 4px solid var(--color-accent);
padding: 16px 20px;
margin: 24px 0;
border-radius: 0 8px 8px 0;
}
footer {
margin-top: 40px;
padding: 20px 0;
border-top: 1px solid var(--color-border);
color: var(--color-text-light);
font-size: 0.875rem;
text-align: center;
}
/* ===========================
Spacing Utilities
=========================== */
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.mb-3 { margin-bottom: 1.5rem; }
<!-- Updated page structure -->
<body>
<header>
<div class="container">
<h1>Welcome to My Website</h1>
<nav>
<a href="index.html">Home</a> |
<a href="about.html">About</a> |
<a href="recipe.html">Recipes</a> |
<a href="contact.html">Contact</a>
</nav>
</div>
</header>
<main>
<div class="container">
<div class="card">
<h2>About This Site</h2>
<p>This is my first properly structured website...</p>
</div>
<aside>
<h3>Fun Fact</h3>
<p>The first website is still live at info.cern.ch!</p>
</aside>
</div>
</main>
<footer>
<div class="container">
<p>© 2026 Alex Johnson</p>
</div>
</footer>
</body>
🎯 Quick Quiz
Question 1: What are the four layers of the box model, from inside to outside?
Question 2: What does box-sizing: border-box do?
Question 3: How do you horizontally center a block element?
Question 4: What happens when two vertical margins touch?
Question 5: What's the difference between padding and margin?
Summary
🎉 Key Takeaways
- Every HTML element is a rectangular box made of four layers: content → padding → border → margin
- Padding = inner space (background shows through); Margin = outer space (always transparent)
- Use the TRouBLe shorthand:
padding: top right bottom left; - Always add
*, *::before, *::after { box-sizing: border-box; }at the top of your CSS — it makeswidthinclude padding and border - Center block elements with
margin: 0 auto;and a setmax-width - Vertical margins collapse — the larger one wins; they don't add together
- Block elements take full width and start on new lines; inline elements flow within text; inline-block gives you the best of both
- Use DevTools (F12) to visually inspect the box model — it's the fastest way to debug spacing
📁 Your Project So Far
my-website/
├── css/
│ └── style.css ← now with box-sizing reset, container, cards
├── images/
│ └── sunset.jpg
├── index.html ← using .container for centered layout
├── about.html
├── recipe.html
└── contact.html
🚀 What's Next?
You can control colors, fonts, and spacing — but everything still flows top to bottom in a single column. What if you want a sidebar next to your main content? A navigation bar with links side by side? A grid of project cards? In the next lesson, you'll learn Flexbox — the modern CSS layout system that makes arranging elements in rows and columns effortless.