CSS Box Sizing
The box-sizing property controls how the browser calculates the total size of an element. It determines whether padding and border are included in the declared width and height, or added on top of them. This one property eliminates one of the most common layout frustrations in CSS.
The Problem
DIAGRAM — The unexpected overflow problem:
You set: .box { width: 200px; padding: 20px; border: 2px solid; }
What you expect:
┌────────────────────┐
│ ←── 200px ────────→│
What the browser actually renders (default behavior):
┌────────────────────────────┐
│ ←─────────── 244px ───────→│
(200px + 20px×2 padding + 2px×2 border = 244px total)
The element is wider than you declared. This breaks layouts, causes horizontal scrollbars, and makes column grids overflow their containers.
Two Values for box-sizing
content-box (Browser Default)
The declared width and height apply to the content area only. Padding and border are added on top, making the element larger than declared.
/* content-box is the default — you never need to write this */
.box {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 2px solid black;
}
/* Total rendered width = 200 + 20 + 20 + 2 + 2 = 244px */
DIAGRAM — content-box breakdown:
│ border │ padding │ content (200px) │ padding │ border │
2px 20px 200px 20px 2px
Total width = 244px
border-box
The declared width and height include the padding and border. The content area shrinks to absorb them. The element is exactly as wide as you declared.
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid black;
}
/* Total rendered width = 200px (exactly what you set) */
/* Content area = 200 - 20 - 20 - 2 - 2 = 156px */
DIAGRAM — border-box breakdown:
Total width = 200px (declared)
│ border │ padding │ content (156px) │ padding │ border │
2px 20px 156px 20px 2px
Everything fits inside the 200px.
Side-by-Side Comparison
DIAGRAM — Same CSS, different box-sizing:
Both boxes have: width: 200px; padding: 20px; border: 2px solid;
content-box:
┌──────────────────────────────────────────────────┐
│░░░░░░░░░░ 244px total ░░░░░░░░░░░░░░░░░░░░░░░░░░░│
border-box:
┌────────────────────────────────┐
│░░░░░░░ 200px total ░░░░░░░░░░░░│
border-box keeps your declared width. content-box grows beyond it.
The Universal border-box Reset
Virtually every modern CSS project starts with this reset. It changes the default for every element on the page.
*, *::before, *::after {
box-sizing: border-box;
}
This rule uses the universal selector (*) to apply border-box to every element and their pseudo-elements. It is the first rule in most professional stylesheets, frameworks like Bootstrap, and CSS resets.
Why Include ::before and ::after?
Pseudo-elements are separate boxes. Without targeting them explicitly, they inherit content-box from their parent, which can cause subtle sizing inconsistencies in complex layouts.
Practical Layout Example
The Two-Column Problem
/* Two columns that should each be 50% */
.col {
width: 50%;
padding: 16px;
float: left;
}
DIAGRAM — content-box breaks the two-column layout:
Page width: 1000px
Col 1: 50% + 32px padding = 532px
Col 2: 50% + 32px padding = 532px
Total: 1064px — overflows the 1000px page!
Result: second column drops to the next line.
DIAGRAM — border-box fixes it:
*, *::before, *::after { box-sizing: border-box; }
Col 1: 50% = 500px (padding is INSIDE the 500px)
Col 2: 50% = 500px
Total: 1000px — fits perfectly, side by side.
When Does box-sizing Matter Most?
- Grid and flex layouts — percentage widths behave predictably with
border-box. - Input fields — setting an input to
width: 100%withcontent-boxcauses it to overflow its parent when padding is added. - Sidebar + main content — fixed plus flexible column layouts break without
border-box. - Card grids — equal-width cards with consistent padding are much easier with
border-box.
Checking the Computed Size in DevTools
Open browser DevTools (F12), click an element, and look at the Box Model panel. It shows a visual diagram of the content area, padding, border, and margin, plus the computed sizes. This makes it easy to see which rule is controlling the dimensions.
box-sizing and height
box-sizing applies to both width and height. When you set a fixed height, padding and border are included inside it with border-box, just like width.
.header {
box-sizing: border-box;
height: 60px;
padding: 12px 24px;
/* Content area height = 60 - 12 - 12 = 36px */
/* Total height stays at exactly 60px */
}
Quick Reference
| Property Value | Width = Content Only | Total = Content + Padding + Border |
|---|---|---|
| content-box (default) | Yes | Yes (grows beyond declared width) |
| border-box | No — includes padding + border | Total = declared width exactly |
Add the universal border-box reset to every project you start. It makes CSS behave the way your brain expects — the number you write is the number you get.
