The box model: every element is a rectangular box with content, padding, border, margin
Default box-sizing is content-box: declared width excludes padding and border
Border-box includes padding and border in width — the production standard
Margin is outside (transparent), padding inside (background fills it)
Vertical margins collapse to the larger value; horizontal margins never collapse
Browser DevTools Computed tab shows the real box model in 2 seconds
Plain-English First
Imagine every element on a webpage is a framed photo hanging on a wall. The photo itself is the content. The white space between the photo and the frame is the padding. The frame itself is the border. And the gap between this frame and the next one on the wall is the margin. CSS is simply the set of instructions you give the browser to style each of those framed photos — their size, colour, font, and spacing. Once you see it that way, CSS stops feeling random and starts feeling logical.
Every website you've ever visited — from Google's homepage to your favourite online shop — is built on three technologies working together: HTML for structure, JavaScript for behaviour, and CSS for visual appearance. CSS is what separates a wall of plain black text from a polished, professional interface. Without it, the web would look like a 1994 university library page. Understanding CSS isn't optional for anyone building for the web; it's the difference between shipping something people trust and something they immediately close.
The single biggest source of confusion for CSS beginners is spacing. Why is my button too big? Why is there a mysterious gap under my image? Why did adding a border break my layout? Almost every one of those questions has the same answer: you don't fully understand the CSS Box Model yet. The box model is the rulebook the browser uses to calculate how much space every element takes up on screen. Master it, and layout clicks into place.
By the end of this article you'll be able to write real CSS that styles text, sets colours and backgrounds, controls spacing with margin and padding, adds borders, and — most importantly — predict exactly how much space an element will occupy before you even open the browser. You'll also know the one property that most tutorials forget to mention, which trips up even experienced developers.
What CSS Actually Is — Selectors, Properties and Values
CSS stands for Cascading Style Sheets. Don't worry about the 'cascading' part yet — we'll get there. For now, think of CSS as a list of rules. Each rule says: 'Find these elements on the page, and make them look like this.'
Every CSS rule has three parts. A selector tells the browser which element to target. A property tells it what aspect to change (colour, size, font, etc). And a value tells it what to change it to. The syntax looks like this: selector { property: value; }. That's the entire grammar of CSS in one line.
You can write CSS in three places: directly in an HTML tag using the style attribute (called inline styles), inside a style tag in your HTML file (called internal styles), or in a completely separate .css file linked to your HTML (called external styles). For anything beyond a quick experiment, always use an external file. It keeps your HTML readable and lets you reuse styles across multiple pages without copying and pasting.
Selectors are how you aim. The three you'll use every day are the element selector (targets all tags of a type, like p or h1), the class selector (targets any element with a matching class attribute, written with a dot like .card), and the ID selector (targets one unique element, written with a hash like #main-header). Classes are the workhorse — use them constantly. IDs are for one-off unique elements.
styles.cssCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* ── Element selector ─────────────────────────────────────────────────────
Targets every <p> tag on the page.
'color' sets the text colour. 'font-size' sets how big the text appears. */
p {
color: #333333; /* Dark grey — easier on the eyes than pure black */
font-size: 16px; /* 16px is the browser default — we're being explicit */
line-height: 1.6; /* 1.6x the font size — makes reading comfortable */
}
/* ── Class selector ───────────────────────────────────────────────────────
Targets any element that has class="highlight-box" in the HTML.
A class can be reused on as many elements as you like. */
.highlight-box {
background-color: #fffbcc; /* Pale yellow background */
color: #5a4a00; /* Dark warm text for contrast */
font-weight: bold; /* Makes the text thicker / heavier */
}
/* ── ID selector ──────────────────────────────────────────────────────────
Targets the ONE element with id="page-title" in the HTML.
UseIDs sparingly — one per page per unique landmark. */
#page-title {
font-size: 32px;
color: #1a1a2e; /* Deep navy — feels professional */
text-align: center; /* Centre the heading horizontally */
}
/* ── Combining selectors ──────────────────────────────────────────────────
You can target multiple selectors at once by separating with a comma.
Both h2 and h3 will get the same bottom border. */
h2,
h3 {
border-bottom: 2px solid #e0e0e0; /* Subtle dividing line below headings */
padding-bottom: 4px; /* Small gap between text and the line */
}
Output
No console output — CSS is visual. When linked to an HTML file:
• All <p> text renders dark grey at 16px with comfortable line spacing.
• Any element with class="highlight-box" gets a yellow background and bold text.
• The element with id="page-title" appears large, navy, and centred.
• All <h2> and <h3> tags display a light grey underline.
Pro Tip: Class Over ID for Styling
Reserve ID selectors for JavaScript hooks and anchor links — not for CSS styling. Classes are reusable, composable and easier to maintain. A rule of thumb: if you find yourself writing two IDs that look almost identical in your CSS, you should have used a class from the start.
Production Insight
In a production dashboard, a developer used an ID selector for a utility style that needed to appear on multiple pages. They ended up duplicating the ID across pages, breaking HTML validation. Stick to classes for reusable styles.
The moment you need to apply the same style to more than one element, use a class — not an ID.
Key Takeaway
CSS rules need a selector, a property and a value.
Use classes for everything except unique landmarks.
External stylesheets keep your project maintainable.
The CSS Box Model — The Four Layers Every Element Has
Here's the mental model that changes everything. Every single element on a webpage — a paragraph, a button, an image, a div — is a rectangular box. Even if it looks round or irregular, the browser is still treating it as a rectangle underneath. And every one of those boxes is built from four nested layers.
The innermost layer is the content — your actual text, image, or whatever is inside the element. Wrapping around the content is the padding — transparent space inside the element, between the content and the border. Think of it as interior cushioning. Next comes the border — an optionally visible line around the element. Finally, on the outside, is the margin — transparent space between this element and everything around it.
Here's the critical part that confuses almost everyone. By default, when you set width: 200px on an element, you're only setting the width of the content area. The browser then adds padding and border on top of that. So if you set width: 200px, padding: 20px and border: 5px, the element actually takes up 250px (200 + 20 left + 20 right + 5 left + 5 right). That unexpected size jump is the #1 source of broken layouts for beginners.
The fix is one line of CSS that every professional stylesheet starts with. We'll cover it in the code example below — and once you understand why it works, you'll never forget it.
box-model-demo.cssCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* ── THEFIX: Applythis at the top of every stylesheet you ever write ────
box-sizing: border-box tells the browser: when I say width: 200px,
I mean the TOTAL width including padding and border — not just the content.
The * selector targets every element on the page.
::before and ::after target pseudo-elements (generated content). */
*,
*::before,
*::after {
box-sizing: border-box; /* The single most important CSS reset line */
}
/* ── Demo: A product card ─────────────────────────────────────────────────
Let's build a simple card to see every layer of the box model at work. */
.product-card {
width: 300px; /* Total width = 300px (because of border-box) */
/* PADDING — space INSIDE the card, between content and border */
padding-top: 20px;
padding-right: 24px;
padding-bottom: 20px;
padding-left: 24px;
/* Shorthandfor the line above: padding: 20px 24px; (top/bottom, left/right) */
/* BORDER — the visible frame around the card */
border: 2px solid #d0d0d0; /* 2px thick, solid line, light grey */
border-radius: 8px; /* Rounds the corners — doesn't affect box model */
/* MARGIN — space OUTSIDE the card, between it and other elements */
margin-bottom: 24px; /* Push the next card 24px below this one */
margin-left: auto; /* Auto left + right margin = horizontally centred */
margin-right: auto;
/* Visual styling */
background-color: #ffffff;
font-family: Arial, sans-serif;
}
.product-card__title {
font-size: 20px;
color: #1a1a2e;
margin-top: 0; /* Removedefault browser top margin on headings */
margin-bottom: 8px;
}
.product-card__price {
font-size: 24px;
font-weight: bold;
color: #e63946; /* Red price — draws the eye */
margin: 0;
}
.product-card__description {
font-size: 14px;
color: #555555;
line-height: 1.5;
margin-top: 12px;
margin-bottom: 0;
}
/* ── Padding shorthand reference ──────────────────────────────────────────
padding: 20px; all four sides = 20px
padding: 20px 24px; top & bottom = 20px, left & right = 24px
padding: 10px 20px 30px; top=10, left&right=20, bottom=30
padding: 10px 20px 30px 40px; top, right, bottom, left (clockwise) */
Output
Visual output in browser:
• A white card, 300px wide, centred on the page.
• 20px of breathing room above and below the text, 24px on the sides (padding).
• A subtle 2px grey frame with rounded corners (border).
• 24px of gap below the card before the next element (margin).
• Because of border-box, the card stays exactly 300px — border doesn't bloat it.
Watch Out: Default box-sizing is content-box
Browsers ship with box-sizing: content-box as the default. That means width + padding + border = actual rendered size. Without the * { box-sizing: border-box } reset at the top of your CSS, you'll spend hours debugging layouts that are a few mysterious pixels too wide. Add it to every project. No exceptions.
Production Insight
A common production issue: a developer set width: 100% on a sidebar, then added padding and border for visual styling. The sidebar overflowed its container by 48px, causing horizontal scroll. The fix — box-sizing: border-box — was a one-line change that resolved the issue globally.
The rule: always include the universal box-sizing reset before any other CSS.
Key Takeaway
Every element has content, padding, border, margin.
Default box-sizing is content-box: width = content only.
Add * { box-sizing: border-box } to every project — it makes width mean total width.
Margin vs Padding — Knowing Which One to Use When
Margin and padding both create space, so beginners often swap them and wonder why things look slightly off. Here's a clear rule: padding is space inside the element; margin is space outside the element. The practical difference matters more than you'd think.
Background colour and border stop at the edge of padding. They don't extend into margin. So if your element has a background colour and you want the colour to extend further into the space around your text, you need more padding. If you want empty air between two separate elements, you need margin.
There's also a quirk called margin collapse that only affects top and bottom margins (never left/right). When two vertically stacked elements both have vertical margins, the browser doesn't add them together — it uses whichever is larger. So if one element has margin-bottom: 30px and the next has margin-top: 20px, the actual gap between them is 30px, not 50px. This is intentional (it makes typography spacing consistent) but it confuses everyone the first time they encounter it.
A practical rule for deciding which to use: if you're adding space between an element and its neighbours, use margin. If you're adding breathing room between an element's edge and its own content, use padding. Think of a button: the text-to-edge gap is padding, the gap between the button and other buttons is margin.
margin-vs-padding.cssCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* ── Demonstrating the visual difference between margin and padding ────── */
/* Reset so we start from a clean slate */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* A container with a background to make spacing visible */
.notification-banner {
background-color: #e8f4fd; /* Light blue — clearly bounded area */
border: 1px solid #90caf9;
border-radius: 6px;
/* PADDING: space between the banner's edge and the text inside it.
Removethis and the text will press right up against the border. */
padding: 16px 20px;
/* MARGIN: space between this banner and whatever comes before/after it.
The background colour does NOT extend into this space. */
margin-bottom: 20px;
font-family: Arial, sans-serif;
font-size: 15px;
color: #1565c0;
}
/* ── Margin collapse in action ────────────────────────────────────────────
These two paragraphs are stacked vertically.
p.first has margin-bottom: 40px.
p.second has margin-top: 24px.
The actual gap between them will be 40px — NOT 64px.
The browser collapses them and keeps the larger value. */
p.first-paragraph {
margin-bottom: 40px; /* This one wins — it's larger */
background-color: #fff3cd;
padding: 8px 12px;
}
p.second-paragraph {
margin-top: 24px; /* This gets collapsed/ignored — smaller value */
background-color: #d4edda;
padding: 8px 12px;
}
/* ── Button spacing: padding for internal room, margin for external gap ─── */
.action-button {
display: inline-block;
background-color: #1a73e8;
color: #ffffff;
font-size: 15px;
font-weight: bold;
/* PADDING pushes the edges of the button away from the text */
padding: 12px 28px;
/* MARGIN creates space between this button and a sibling button */
margin-right: 12px;
border: none;
border-radius: 4px;
cursor: pointer;
}
Output
Visual output in browser:
• The notification banner has 16px top/bottom and 20px left/right of internal
breathing room — the blue background fills that space.
• 20px of empty (no background) space appears below the banner.
• The gap between .first-paragraph and .second-paragraph is exactly 40px,
not 64px — margin collapse in action.
• The button is comfortably sized from padding, with 12px of air to its right.
Interview Gold: Margin Collapse
Margin collapse is one of the most-asked CSS interview topics. Remember: it only happens vertically (top/bottom), never horizontally. It also doesn't happen when an element is a flex container or grid container — those layouts disable margin collapsing between their children. Mention that in an interview and you'll stand out.
Production Insight
A product listing page had a 60px gap between two stacked divs — a heading with margin-bottom: 30px and a paragraph with margin-top: 30px. The gap measured 30px, not 60px. The designer complained. The developer added a wrapper with padding-top: 30px instead of relying on the second element's margin.
When you need a guaranteed gap, apply margin to only one of the two elements, or use a flex container.
Key Takeaway
Padding = inside, margin = outside.
Background fills padding, never margin.
Vertical margins collapse to the larger value — use flex to disable it.
Debugging Box Model Issues in the Browser DevTools
The browser's Developer Tools are your best friend for diagnosing box model problems. No guessing, no trial-and-error. The Computed tab shows you exactly what the browser is using for every layer of the box.
Open DevTools (F12 on Windows/Linux, Cmd+Option+I on Mac), select an element, and go to the Computed tab. You'll see a visual diagram of the box model: content, padding, border, margin — all with exact pixel values. Hover over each section to see the dimensions breakdown.
Here's a common workflow: you notice an element is wider than you intended. Open Computed, look at the width value. If it's bigger than your CSS width, the extra is coming from padding or border being added on top. The solution is either to reduce padding/border or add box-sizing: border-box. The DevTools also show you which CSS rule sets each property — so you can trace it back to the source file and line number.
Another powerful trick: use the :hov button in the Styles panel to force element states like :hover or :focus. This lets you debug interactive states without having to keep hovering. Also use the 'Toggle Element State' feature to see how padding or margins change on hover.
debugging-devtools.cssCSS
1
2
3
4
5
6
7
8
9
10
11
12
13
/* No code forthis section — it's about using DevTools.
But here's a quick CSS snippet to test the box model visually. */
.debug-card {
width: 200px;
padding: 30px 20px;
border: 10px solid red;
margin: 50px auto;
background: #e0e0e0;
}
/* After applying this, open DevTools → Computed tab →
see that the total width is 200 + 20+20 + 10+10 = 260px.
Changing box-sizing to border-box reduces it to 200px. */
Output
In DevTools Computed tab: Box Model diagram shows:
• Content: 160px × (depending on text)
• Padding: 20px left + 20px right
• Border: 10px left + 10px right
• Margin: 50px top + 50px bottom, auto left+right
Total width: 260px. After box-sizing: border-box → total width: 200px.
DevTools Shortcut: $0 in Console
Select an element in the Elements panel, then switch to the Console tab and type $0. You'll get a reference to that DOM element. You can inspect its style properties with getComputedStyle($0). This is faster than clicking through panels when you're debugging programmatically.
Production Insight
A finance dashboard had a chart that appeared cut off on small screens. The developer used DevTools to discover the chart's parent had a fixed width and overflow: hidden, while the chart itself had margin-left: -20px to align labels. The negative margin pushed the chart outside the parent, and overflow clipped it. The fix: remove the negative margin and use padding on the parent.
DevTools is the first tool to open when layout doesn't match your CSS expectations.
Key Takeaway
DevTools Computed tab shows the exact box model.
Use it to see where unexpected width comes from.
Negative margins can cause overflow — check the parent container's overflow property.
Putting It All Together — A Real Styled Web Card
The best way to cement CSS basics and the box model is to build something real from scratch. No contrived examples — let's style an actual profile card you could drop into a real project today.
The HTML gives us the structure: a container div with a profile image, a name, a job title, and a short bio. The CSS then layers on typography, colour, spacing, and a subtle shadow using everything we've covered. Read each comment in the code carefully — there's intentional teaching in every property choice.
Pay attention to how margin: 0 auto centres the card horizontally. This works on block elements with a defined width. The auto value tells the browser to distribute remaining horizontal space equally on both sides — which centres the element. It's one of those CSS tricks that's been around since the early 2000s and still works perfectly today.
Also notice the use of a box-shadow. It isn't part of the box model — it doesn't affect layout at all. Box shadows are purely decorative and are drawn outside the element without changing its size or pushing anything around. That makes them safe to add to any element without worrying about breaking your layout.
profile-card.htmlHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ProfileCard — CSSBoxModelDemo</title>
<style>
/* ── Global reset ────────────────────────────────────────────────────
Always start here. Every professional project does this. */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0; /* Remove all default browser margins */
padding: 0; /* Remove all default browser padding */
}
/* ── Page background ─────────────────────────────────────────────── */
body {
background-color: #f0f2f5; /* Soft grey — makes white cards pop */
font-family: 'Segoe UI', Arial, sans-serif;
display: flex; /* Center the card on the page */
justify-content: center; /* Horizontal centre in flex */
align-items: center; /* Vertical centre in flex */
min-height: 100vh; /* Full viewport height */
padding: 24px; /* Breathing room on small screens */
}
/* ── The card itself ─────────────────────────────────────────────── */
.profile-card {
background-color: #ffffff;
width: 320px; /* Fixed width — border-box keeps it exact */
border-radius: 12px; /* Rounded corners — modern feel */
/* Box shadow: horizontal-offset vertical-offset blur spread colour
This creates depth — the card appears to float above the page.
Crucially, box-shadow does NOT affect the box model — it adds
no size and pushes nothing around. */
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.10);
overflow: hidden; /* Clips the avatar image to card edges */
}
/* ── Coloured header strip at the top of the card ────────────────── */
.profile-card__header {
background-color: #1a73e8; /* Brand blue */
height: 80px; /* Fixed height for the colour strip */
}
/* ── Avatar: the circular profile photo ─────────────────────────── */
.profile-card__avatar {
display: block;
width: 80px;
height: 80px;
border-radius: 50%; /* 50% border-radius = perfect circle */
border: 4px solid #ffffff; /* White ring makes it stand out */
background-color: #4caf50; /* Placeholder — replace with <img> */
/* Pull the avatar up over the header strip using negative margin */
margin-top: -40px; /* Negative margin — overlaps the header */
margin-left: 24px; /* Align to left with breathing room */
}
/* ── Card body: all the text content ─────────────────────────────── */
.profile-card__body {
padding: 12px 24px 24px 24px; /* Less top padding — avatar took some space */
}
.profile-card__name {
font-size: 20px;
font-weight: 700; /* Bold weight — 700 is standard bold */
color: #1a1a2e;
margin-bottom: 4px; /* Tight gap before job title */
}
.profile-card__job-title {
font-size: 13px;
font-weight: 500;
color: #1a73e8; /* Blue — ties back to the header colour */
text-transform: uppercase; /* ALLCAPSfor the job title */
letter-spacing: 0.05em; /* Slight spacing between letters */
margin-bottom: 16px; /* Bigger gap before bio paragraph */
}
.profile-card__bio {
font-size: 14px;
color: #555555;
line-height: 1.6; /* 1.6x line height = comfortable reading */
}
/* ── Follow button ───────────────────────────────────────────────── */
.follow-button {
display: block; /* Block so we can set width */
width: 100%; /* Full width of the card body */
margin-top: 20px;
padding: 12px 0; /* Top/bottom padding — no left/right needed */
background-color: #1a73e8;
color: #ffffff;
font-size: 15px;
font-weight: 600;
text-align: center;
border: none;
border-radius: 8px;
cursor: pointer;
}
/* Hover state — interactive feedback */
.follow-button:hover {
background-color: #1558b0; /* Darker blue on hover */
}
</style>
</head>
<body>
<div class="profile-card">
<!-- Blue header strip -->
<div class="profile-card__header"></div>
<!-- Circularavatar (use an <img> tag in production) -->
<div class="profile-card__avatar"></div>
<!-- Text content -->
<div class="profile-card__body">
<h2 class="profile-card__name">SarahChen</h2>
<p class="profile-card__job-title">SeniorFrontendEngineer</p>
<p class="profile-card__bio">
Building fast, accessible web interfaces for over 8 years.
Passionate about clean CSS architecture and performance.
</p>
<button class="follow-button">Follow</button>
</div>
</div>
</body>
</html>
Output
Visual output in browser:
• A white 320px card centred on a soft grey page.
• A solid blue strip across the top, with a green circle (avatar placeholder)
half-overlapping the strip using negative margin.
• Name in bold navy, job title in small blue caps, bio in readable grey text.
• A full-width blue Follow button at the bottom that darkens on hover.
• The card has a soft drop shadow, appearing to float above the page.
• Everything fits exactly — border-box prevents any dimension surprises.
Pro Tip: Negative Margin is a Feature, Not a Hack
Using margin-top: -40px to overlap the avatar over the header strip is a legitimate technique — not a hack. Negative margins pull elements toward their neighbours rather than pushing them away. They're particularly useful for overlap effects. Just use them intentionally, not to paper over a layout you don't understand.
Production Insight
A profile card in a SaaS app used negative margin to overlap a photo, but the card below it had margin-top: 0. When the photo was removed, the negative margin collapsed differently, causing a gap. The fix: always pair negative margins with a predictable sibling margin, or use relative positioning instead.
Negative margins are powerful but need stable sibling margins to remain predictable.
Key Takeaway
Build real components to cement the box model.
Box-shadow doesn't affect layout — use it freely.
Negative margins create overlap effects but require a stable context.
● Production incidentPOST-MORTEMseverity: high
The Mystery 20px Overflow That Broke a Checkout Page
Symptom
A green 'Place Order' button rendered 40px wider than its parent container on all viewports. Horizontal scrollbar appeared on the checkout page. No amount of width adjustments fixed it.
Assumption
The team assumed the button had a min-width or a flex-grow issue. They added overflow: hidden to the parent, which clipped the button but didn't fix the layout—the button was still overlapping other elements.
Root cause
The button had width: 100%; padding: 20px 30px; border: 2px solid #ccc;. With default box-sizing: content-box, the actual rendered width was 100% + 60px + 4px = 100% + 64px. That extra 64px pushed it out of the parent.
Fix
Added * { box-sizing: border-box; } at the top of the stylesheet. The button then respected width: 100% including padding and border. The overflow disappeared instantly.
Key lesson
Always include box-sizing: border-box as a global reset in every project
Never assume width means total width — check box-sizing first
When an element overflows, the computed tab in DevTools confirms the box model instantly
Production debug guideQuick diagnostic path for the 3 most common box model failures in production3 entries
Symptom · 01
Element is wider than its declared width
→
Fix
Open DevTools → Computed tab. If width shows content-box width + padding + border, add box-sizing: border-box. Verify the parent container doesn't have overflow: hidden clipping the extra.
Symptom · 02
Gap between two stacked boxes is smaller than expected
→
Fix
Check both elements' margin-top and margin-bottom. Use DevTools to see which margin collapsed. If collapse is unwanted, move both margins to one element or add a flex container.
Symptom · 03
Background colour doesn't extend to the edge of the element
→
Fix
Inspect the element's padding. If padding is set on the outer element, background fills it. If you set margin on the inner element, background stops at the margin – use padding on the parent instead.
★ Box Model Debug Cheat SheetBrowser DevTools commands for common box model issues. All actions from the Elements panel.
Element wider than expected−
Immediate action
Inspect element → Computed tab → view Box Model diagram
Commands
Right-click element → Inspect → Computed tab (or press F12, then Ctrl+Shift+E in Firefox)
Check if box-sizing is content-box or border-box. Look for padding adding to width
Fix now
Add * { box-sizing: border-box; } to CSS. Change width to max-width if parent constraint is the real issue
Vertical gap between siblings is not summing+
Immediate action
Select first element → Computed tab → check margin-bottom, then second element → margin-top
Commands
In first element: styles panel → check margin-bottom value. In second: margin-top
Recognise collapse: if both values differ, the browser uses the larger one, not the sum
Fix now
Add only margin-bottom to the first element, set margin-top: 0 on the second. Or wrap them in a flex container (flex disables collapsing)
In DevTools, click the `+` button in Styles to add a new property: `padding: 12px 20px`
Check if the button has a fixed width that becomes too tight after adding padding. If so, switch to `width: auto` or `box-sizing: border-box`
Fix now
Set padding on the button element, not margin on the inner text. Use padding: 0.75em 1.5em for responsive spacing
Padding vs Margin: Complete Comparison
Aspect
padding
margin
Where it creates space
Inside the element, between content and border
Outside the element, between it and neighbours
Background colour fills it?
Yes — background extends into padding
No — margin is always transparent
Border extends into it?
No — border wraps around padding
No — border stops at padding's edge
Collapses vertically?
Never — padding never collapses
Yes — vertical margins collapse to the larger value
Use it when...
You want internal breathing room inside an element
You want space between separate elements
Affected by box-sizing?
Yes — border-box includes padding in total width
No — margin is always added outside the total width
Can be negative?
No — padding cannot be negative
Yes — negative margin pulls elements closer or overlaps them
Affects clickable area?
Yes — padding is part of the clickable element
No — clicking in a margin doesn't trigger the element
Key takeaways
1
Every HTML element is a box made of four layers
content → padding → border → margin. Knowing which layer you're working with solves most layout bugs instantly.
2
Always start your CSS with * { box-sizing
border-box; }. Without it, padding and border add to your declared width — creating mystery pixels that break layouts.
3
Padding creates space inside an element (the background fills it); margin creates space outside (transparent, never coloured). Swapping them gives visually wrong results even when the spacing amount looks right.
4
Vertical margins between block elements collapse to the larger value, not the sum. This doesn't happen in flex or grid containers, and never affects horizontal margins.
5
Browser DevTools Computed tab is your box model debugger
it shows exact values for content, padding, border, and margin. Use it before guessing.
Common mistakes to avoid
3 patterns
×
Forgetting box-sizing: border-box
Symptom
You set width: 300px and add padding: 20px, but the element renders at 340px, overflowing its container or breaking the layout.
Fix
Add * { box-sizing: border-box; } at the very top of your stylesheet before writing any other CSS. This should be in every single project you ever create.
×
Using margin to push content away from an element's own border
Symptom
You want space between text and the edge of a coloured box, so you add margin to the text element. The background colour doesn't extend into that gap, leaving a blank white strip instead of the intended padding.
Fix
Use padding on the outer container element, not margin on the inner content. Padding lives inside the background; margin lives outside it.
×
Being surprised by margin collapse
Symptom
You have two stacked divs, one with margin-bottom: 40px and one with margin-top: 30px. You expect 70px of space, but you measure only 40px.
Fix
Remember that vertical margins between block siblings collapse to the larger value, not the sum. To intentionally add 70px of space, use padding on the parent element or apply the space only to one element (e.g., only use margin-bottom on the first div, leave the second with no top margin).
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
Q01JUNIOR
Can you explain the CSS box model and describe what each layer — content...
Q02SENIOR
What is margin collapse? When does it happen and when doesn't it? Give m...
Q03JUNIOR
If I set width: 500px, padding: 25px, and border: 5px on a div — what's ...
Q01 of 03JUNIOR
Can you explain the CSS box model and describe what each layer — content, padding, border and margin — actually does? How does box-sizing: border-box change the calculation?
ANSWER
The CSS box model defines that every element is a rectangular box: content (the actual content), padding (space between content and border, extends background), border (an optional visible outline), and margin (space outside the element, transparent). By default (content-box), the declared width only covers content — padding and border are added. With box-sizing: border-box, the declared width includes padding and border, so the total rendered width equals the set width. This makes layout more predictable.
Q02 of 03SENIOR
What is margin collapse? When does it happen and when doesn't it? Give me a concrete example of two elements where you'd expect the gaps to add up, but they don't.
ANSWER
Margin collapse is when vertical margins of adjacent block-level elements overlap and combine into the larger of the two instead of summing. For example, a heading with margin-bottom: 40px followed by a paragraph with margin-top: 30px results in a 40px gap, not 70px. It only happens for vertical (top/bottom) margins, never horizontal. It does not happen when elements are inside a flex or grid container, or when an element has a border, padding, or overflow: hidden that creates a new block formatting context.
Q03 of 03JUNIOR
If I set width: 500px, padding: 25px, and border: 5px on a div — what's the actual rendered width with the default box-sizing? What would it be with border-box applied? Walk me through the arithmetic.
ANSWER
With content-box (default): width = content width = 500px. Total rendered width = 500 + 25 left padding + 25 right padding + 5 left border + 5 right border = 560px. With border-box: width includes padding and border, so content width = 500 - 50 - 10 = 440px. Total rendered width = 500px. So border-box makes the declared width the total width.
01
Can you explain the CSS box model and describe what each layer — content, padding, border and margin — actually does? How does box-sizing: border-box change the calculation?
JUNIOR
02
What is margin collapse? When does it happen and when doesn't it? Give me a concrete example of two elements where you'd expect the gaps to add up, but they don't.
SENIOR
03
If I set width: 500px, padding: 25px, and border: 5px on a div — what's the actual rendered width with the default box-sizing? What would it be with border-box applied? Walk me through the arithmetic.
JUNIOR
FAQ · 5 QUESTIONS
Frequently Asked Questions
01
What is the CSS box model in simple terms?
The CSS box model is the rule that every element on a webpage is a rectangular box made of four layers: the content in the middle, padding (space inside between content and the edge), a border (the visible frame), and margin (space outside between this element and others). The browser uses these four layers to calculate how much room every element takes up on screen.
Was this helpful?
02
What does box-sizing: border-box actually do?
By default, when you set width: 300px on an element, that 300px only covers the content area. The browser then adds padding and border on top, making the element larger than you specified. Setting box-sizing: border-box changes this so that your declared width includes padding and border — meaning width: 300px always means 300px total, period. This makes layout far more predictable.
Was this helpful?
03
When should I use padding vs margin?
Use padding when you want breathing room inside an element — between its content and its border. The background colour and border apply to the padding area. Use margin when you want space between two separate elements — it's always transparent and sits outside the element's background. A good test: if you want the gap to share the element's background colour, use padding. If you want empty air between two things, use margin.
Was this helpful?
04
How can I debug a mysterious extra space in my layout?
Open your browser's Developer Tools (F12), inspect the problematic element, and go to the Computed tab. You'll see a visual box model diagram with exact pixel values for content, padding, border, and margin. This immediately shows you where the extra space is coming from — most often it's padding or border being added on top of a content-box width.
Was this helpful?
05
Does margin collapse happen horizontally?
No. Margin collapse only affects vertical (top and bottom) margins between block-level siblings. Left and right margins never collapse. Also, margin collapse is disabled inside flex and grid containers, and when an element has its own new block formatting context (e.g., via overflow: hidden or floating).