Spacing and sizing bugs almost always come from misunderstanding how these four layers add up.
The browser lays out every element as a rectangular box with four layers, from inside out:
- content: the text or child elements, sized by
width/height; - padding: space inside the border, which shows the element's background;
- border: the visible edge;
- margin: transparent space outside, pushing neighbours away.
By default (box-sizing: content-box) width sets only the content. A width: 300px box with padding: 20px and border: 1px takes up 342px. Almost every project switches to box-sizing: border-box, where width includes padding and border, so the box is exactly 300px.
Shorthands set four sides clockwise from the top: margin: 10px 20px means 10px top/bottom and 20px left/right. Prefer the logical properties margin-block (top/bottom in horizontal text) and margin-inline (left/right), plus padding-inline-start and friends, which also adapt to right-to-left languages.
margin: 0 auto centers a block that has a width: the auto margins split the free space.
One surprise: vertical margins between block elements collapse. Two paragraphs with margin: 20px are 20px apart, not 40px; the larger margin wins. Padding never collapses, and margins don't collapse inside flex or grid containers.
Open devtools and select an element: the box-model diagram shows each layer's exact size, which is the fastest way to debug spacing.
Example
*, *::before, *::after { box-sizing: border-box; } /* the usual reset */
.card {
width: 300px; /* total width: exactly 300px with border-box */
padding: 20px;
border: 1px solid #ccc;
margin-block: 16px; /* top and bottom */
margin-inline: auto; /* centers the card horizontally */
}
p { margin-block: 1em; } /* adjacent paragraphs: 1em apart, not 2em (collapse) */
.button { padding: 0.5rem 1rem; } /* 0.5rem top/bottom, 1rem left/right */Remember
- content + padding + border + margin
- box-sizing: border-box makes width include padding and border
- margin-inline: auto centers a block with a width
- Vertical margins between blocks collapse to the larger one
Watch out for
- Adding padding to a width: 100% element with content-box and getting a horizontal scrollbar.