The four layers of every box
Every element on a page is drawn as a rectangle made of four layers, from the inside out:
- Content: the text, image or child elements, sized by
widthandheight. - Padding: space inside the box, between the content and the border. It shows the element's background.
- Border: the line around the padding.
- Margin: space outside the border that pushes other boxes away. Always transparent.
In the example each layer has its own color: blue content, green padding, a dark border, and an amber area around the box that is the margin (drawn by a wrapper, since a margin itself is transparent).
The line under the box is measured by the browser: 160 + 20 + 20 + 10 + 10 = 220px. The margin adds another 24px on each side of that, but it is outside the box, so it is not part of the 220.
Width math: content-box vs border-box
By default (box-sizing: content-box), width sets only the content. Padding and border are added on top, so the box ends up wider than the number you wrote. With box-sizing: border-box, width is the whole box, and the content shrinks to make room for the padding and border.
content-box (default) | border-box | |
|---|---|---|
width means | The content | Content + padding + border |
width: 200px; padding: 20px; border: 5px | 250px wide | 200px wide |
| Content area in that case | 200px | 150px |
| Margin | Outside, not counted | Outside, not counted |
The border-box reset
Because border-box makes sizes add up, almost every modern stylesheet starts with this rule:
*,
*::before,
*::after {
box-sizing: border-box;
}
It matters most with percentages. Two width: 50% columns with padding do not fit on one line under content-box, because each is 50% plus its padding:
(The HTML comments remove the space between the inline-block columns, which would otherwise add a few pixels.)
Seeing the box model in DevTools
Every browser draws the box model for you. Right-click an element, choose Inspect, and open the Computed tab (Layout in Firefox): a diagram shows the content size in the middle, surrounded by the padding, border and margin values. Hovering an element in the Elements panel also tints the page: content blue, padding green, margin orange.
Inline boxes follow different rules
The box model above describes block boxes such as <div> and <p>. Inline elements like <span>, <a> and <strong> wrap inside a line of text, and they treat vertical space differently:
| Property | On an inline element |
|---|---|
width, height | Ignored |
| Horizontal padding, border, margin | Applied, and push neighbors sideways |
| Vertical padding and border | Drawn, but do not push the lines above and below |
| Vertical margin | Ignored |
display: inline-block gives an element inside a line the full box model: its width, height, padding and margin all take up space. See CSS padding and CSS margin for each layer in detail.
Common mistakes
- Adding padding to a fixed-width box and wondering why it grew. Under
content-box, padding and border are added towidth. Useborder-box. - Expecting margin to take the background color. Margin is always transparent; use padding for colored space.
- Setting
heightor vertical margin on an inline element. Nothing happens; usedisplay: inline-blockorblock. - Forgetting borders in the math. A 1px border on a
width: 100%element makes it 2px too wide undercontent-box, which can cause a horizontal scrollbar. - Confusing margin and padding. The short version: padding is inside the border, margin outside. The margin vs padding page puts them side by side.
Frequently Asked Questions
What is the CSS box model?
The rule that every element renders as a rectangular box of four layers: the content, the padding around it, the border around the padding, and the margin outside the border. Width, height and spacing in CSS are all set on these layers.
What does box-sizing: border-box do?
It makes width and height include the padding and border. A width: 200px box with padding: 20px and a 5px border is then exactly 200px wide, and the content area shrinks to 150px to fit. The default, content-box, adds the padding and border on top, giving 250px.
How is the total width of an element calculated?
With the default content-box: width + left and right padding + left and right border. With border-box: just width. Margin is outside the box in both cases, so it adds to the space the element takes up, not to its own width.
Is margin part of the box model?
Yes, it is the outermost layer, but it is always transparent and never counted in the element's own width or background. It only pushes neighboring boxes away.
Should I set box-sizing: border-box on everything?
Most projects do, with *, *::before, *::after { box-sizing: border-box; } at the top of the stylesheet. It makes percentage widths and padding add up the way people expect, and frameworks such as Bootstrap and Tailwind ship the same reset.