HTML & CSS · Lesson 7 of 13
The Box Model, Sizing and Units
Understand the CSS box model in depth: margins, padding, borders, box-sizing, display types, margin collapse, min/max sizing and units like rem, vw and ch.
- Beginner
- 16 min read
- 4 objectives
Before this lessonLesson 6: Selectors, Specificity and the Cascade
What you will learn
- Explain content, padding, border and margin and how box-sizing changes widths
- Know the difference between block, inline and inline-block
- Recognise and avoid margin collapse
- Pick the right unit: px, rem, em, %, vw, ch, and functions like min() and clamp()
Your Progress
0 of 13 lessons 0%
- Lessons0 / 13
- Completed0
- Est. time left~ 4 hours
Create a free account to keep your progress on every device.
Tip: pressing Next marks this lesson complete automatically.
CSS Basics introduced the idea that every element is a box. This lesson goes deeper, because nearly every "why is this 20px too wide?" or "where did that gap come from?" question is a box model question. Once you understand how width is calculated, how elements flow, and which unit to use, layout becomes predictable.
The four layers, and how width is calculated
From the inside out: content, padding, border, margin. By default (box-sizing: content-box), the width you set applies to the content only, and padding and border are added on top.
.box {
width: 300px;
padding: 20px;
border: 5px solid #334155;
margin: 16px;
}
/* content-box: visible width = 300 + 20*2 + 5*2 = 350px */
.box.border-box {
box-sizing: border-box;
}
/* border-box: visible width = 300px exactly (content shrinks to 250px) */Almost every modern project applies border-box everywhere, so widths mean what you expect:
*, *::before, *::after {
box-sizing: border-box;
}Shorthand for margin and padding
The shorthands go clockwise from the top: top, right, bottom, left. Missing values copy their opposite side.
.a { padding: 16px; } /* all four sides */
.b { padding: 8px 16px; } /* vertical | horizontal */
.c { padding: 8px 16px 24px; } /* top | horizontal | bottom */
.d { padding: 8px 16px 24px 32px; } /* top | right | bottom | left */
/* Logical properties follow writing direction (great for RTL languages) */
.e { padding-inline: 16px; margin-block: 24px; }Display: block, inline and inline-block
The display property controls how a box behaves in the normal flow of the page.
- block (
div,p,h1,section): starts on a new line and stretches to fill the width of its parent. Width, height, margin and padding all work. - inline (
span,a,strong): flows within a line of text.widthandheightare ignored, and vertical margins do not push other lines away. - inline-block: sits in a line like text, but respects width, height and all margins. Handy for badges and buttons.
- none: removes the element from the page entirely (and from screen readers).
- flex and grid: turn the element into a layout container, covered in their own lessons.
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 999px;
background: #e0e7ff;
}Margin collapse
When two vertical margins of block elements touch, they collapse into one margin equal to the larger of the two, instead of adding up. It was designed so paragraphs get even spacing, but it surprises everyone at first.
h2 { margin-bottom: 24px; }
p { margin-top: 16px; }
/* Gap between an h2 and the following p is 24px, not 40px */A child's top margin can also collapse through its parent, pushing the parent down instead of creating space inside it. Margins do not collapse inside flex or grid containers, or when the parent has padding or a border.
Width, height and their limits
Fixed widths break on small screens. Instead, let elements be fluid and cap them with max-width. Avoid fixed heights on anything containing text; content grows, and a fixed height causes overflow. Use min-height instead.
.container {
width: 100%;
max-width: 72rem; /* never wider than about 1150px */
margin-inline: auto; /* centre it */
padding-inline: 1rem; /* breathing room on phones */
}
.hero { min-height: 60vh; } /* at least 60% of the screen, grows if needed */
img { max-width: 100%; height: auto; } /* images never overflow their box */
.two-lines { aspect-ratio: 16 / 9; } /* keep a video-like shape */Choosing units
- px: fixed. Good for borders, shadows and small details.
- rem: relative to the root font size (16px by default). Use for font sizes, spacing and widths. If a user sets a larger default font for readability, everything scales with it.
- em: relative to the current element's font size. Useful for padding on buttons so it grows with the button's text.
- %: relative to the parent's size (for width) or the element's font size (for line-height).
- vw / vh: 1% of the viewport width or height. On mobile,
100vhcan be taller than the visible area because of browser toolbars; use100dvh(dynamic viewport height) instead. - ch: the width of the "0" character.
max-width: 65chkeeps text lines at a comfortable reading length.
html { font-size: 100%; } /* respect the user's browser setting */
h1 { font-size: 2.5rem; } /* 40px at default settings */
.btn { font-size: 1rem; padding: 0.5em 1.25em; } /* padding scales with text */
.article { max-width: 65ch; }
.fullscreen { min-height: 100dvh; }Math functions: calc(), min(), max(), clamp()
.sidebar { width: calc(100% - 2rem); } /* mix units */
.card { width: min(100%, 400px); } /* the smaller of the two */
.section { padding: max(1rem, 4vw); } /* the larger of the two */
h1 { font-size: clamp(1.75rem, 4vw + 1rem, 3rem); } /* fluid, with limits */min(100%, 400px) is a one-line replacement for width: 100%; max-width: 400px. The Grid lesson uses clamp() for fluid type, and it works just as well for spacing.
Recap
- A box is content, padding, border and margin; set
box-sizing: border-boxglobally so width includes padding and border. - Block elements stack and fill width; inline elements flow with text and ignore width and height; inline-block mixes both.
- Adjacent vertical margins collapse to the larger value; use one-direction margins or
gapto avoid surprises. - Prefer fluid widths with
max-widthandmin-heightover fixed sizes. - Use rem for most sizing, em for component padding, ch for line length, dvh for full-screen sections, and
clamp()for fluid values.
// Write your solution here
Finished reading? Mark this lesson complete to track your progress.
