CSS Box Model
Every element on a web page is a rectangular box. Understanding the rules that govern how those boxes are sized and spaced is the single most important step toward writing CSS that behaves predictably.
The Four Layers
From innermost to outermost, each box has four regions:
/*
* βββββββββββββββββββββββββββββββββββββββ
* β MARGIN β β transparent, pushes other elements away
* β βββββββββββββββββββββββββββββββββ β
* β β BORDER β β β visible line (or invisible if border: none)
* β β βββββββββββββββββββββββββββ β β
* β β β PADDING β β β β space between content and border
* β β β βββββββββββββββββββββ β β β
* β β β β CONTENT β β β β β text, image, child elements
* β β β βββββββββββββββββββββ β β β
* β β βββββββββββββββββββββββββββ β β
* β βββββββββββββββββββββββββββββββββ β
* βββββββββββββββββββββββββββββββββββββββ
*/
- Content β where text, images, and child elements live. Sized by
widthandheight. - Padding β transparent space between the content and the border. Has the elementβs background color.
- Border β a rendered line around the padding. Can have color, style, and width.
- Margin β transparent space outside the border. Always transparent; never has a background.
content-box vs border-box
The default box-sizing: content-box means width applies only to the content area. If you set width: 200px, padding: 20px, and border: 2px solid, the elementβs rendered width is actually 200 + 40 + 4 = 244px. This is almost never what you intend.
box-sizing: border-box includes padding and border in the width value. A 200px element stays 200px no matter how much padding or border you add.
/* Apply border-box globally β include this in every project reset */
*,
*::before,
*::after {
box-sizing: border-box;
}
.card {
width: 300px;
padding: 24px;
border: 2px solid #e5e7eb;
/* Total rendered width: 300px (padding and border are inside) */
}
IMPORTANT
Always set box-sizing: border-box globally. It is the default in every modern CSS framework (Tailwind, Bootstrap, etc.) and eliminates an entire class of sizing bugs.
Margin Collapse
Vertical margins between block elements collapse β the space between two elements is the larger of the two margins, not their sum. This happens in three situations:
- Adjacent siblings: the bottom margin of one element and the top margin of the next.
- Parent and first/last child when there is no border, padding, or block formatting context between them.
- An element with no content, padding, or border whose top and bottom margins collapse with each other.
/* These two paragraphs are separated by 24px, not 16px + 24px = 40px */
p { margin-bottom: 16px; }
h2 { margin-top: 24px; }
To prevent collapse: add padding, border, overflow: hidden, or display: flex to the parent.
Display Types
| Value | Behavior |
|---|---|
block | New line, full width, respects width/height/margin |
inline | Flows in text, width/height ignored, vertical margin ignored |
inline-block | Flows in text but respects width/height and all margins |
none | Removed from layout entirely (not just invisible) |
/* Making a span act like a block for a badge */
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 9999px;
background: #10b981;
color: white;
font-size: 0.75rem;
}
NOTE
visibility: hidden hides an element but keeps its space in the layout. display: none removes it from the layout entirely. Both leave the element in the DOM.
TIP
In DevTools, hovering over any element in the Elements panel highlights all four box model regions on the page in real time. The Computed panel shows the exact resolved values for every box property.
Further Learning
Search these terms to go deeper:
- βCSS box model MDNβ β the definitive reference with interactive diagrams
- βCSS margin collapse rulesβ β all three collapse scenarios with examples
- βblock formatting context CSSβ β what triggers a BFC and why it stops margin collapse
- βCSS reset vs normalizeβ β different approaches to establishing a predictable baseline
- βCSS logical propertiesβ β
margin-block,padding-inlineand how they work with writing modes