🎁 Understanding Box Sizing
When you set the width and height of an element in CSS, how much space does it actually take up? That’s where box-sizing comes in — it tells the browser how to calculate the total size of an element.
🧁 Real-Life Analogy
Imagine you’re packing a cake box.
The cake is the content.
The butter paper around the cake is the padding.
The cardboard box is the border.
And if you keep some space between two boxes, that’s the margin.
Now, you want your cake box to be 300px wide. But should that 300px include the padding and border, or should padding and border add extra space on top?
That’s the box-sizing question.
📏 Two Types of Box Sizing
box-sizing: content-box; (Default)
Only the content gets the width/height.
Padding and border are added outside.
🧠 So your box can end up larger than expected!
width = content
total width = content + padding + borderbox-sizing: border-box; ✅ (Better control)
The width/height includes content, padding, and border.
No surprises — what you set is what you get!
total width = exact width you define (content shrinks if padding/border added)🧠 Comparison Chart
Property | content-box | border-box |
|---|---|---|
Width includes | Only content | Content + Padding + Border |
Total size | Can grow larger than set value | Stays exactly as set |
Control over layout | Tricky with padding/border | Much easier to manage |
Common use | Rare now | Almost always preferred ✅ |
💻 Code Example
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Box Sizing Anatomy</title>
<style>
.infographic-boxsizing {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
box-sizing: border-box;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: var(--paper);
color: var(--ink);
border-radius: 14px;
overflow: hidden;
}
.infographic-boxsizing[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.ha-inner { padding: 0.5rem; }
.ha-layout { display: flex; flex-direction: column; gap: 1.2rem; }
.ha-code-wrap {
background: #0b0b0b;
border: 1px solid #2a2a2a;
border-radius: 10px;
overflow: hidden;
}
.ha-filetabs {
display: flex;
background: #161616;
border-bottom: 1px solid #2a2a2a;
}
.ha-filetab {
border: none;
background: transparent;
color: #8a8a8a;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.78rem;
font-weight: 700;
padding: 0.6rem 1rem;
cursor: pointer;
border-bottom: 2px solid transparent;
transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.ha-filetab:hover { color: #e5e5e5; }
.ha-filetab.ha-tab-on {
color: #ffffff;
border-bottom-color: #5b8def;
background: #0b0b0b;
}
.ha-code {
padding: 1rem 1.8rem 1rem 0.9rem;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.78rem;
line-height: 1.8;
overflow-x: auto;
}
.ha-codepane { display: none; white-space: pre; color: #e5e5e5; }
.ha-codepane.ha-pane-on { display: block; }
.ha-tag { color: #60a5fa; font-weight: 700; }
.ha-attr { color: #f2b96b; }
.ha-str { color: #9ece6a; }
.ha-sel { color: #f472b6; font-weight: 700; }
.ha-prop { color: #c586c0; }
.ha-val { color: #ce9178; }
.ha-controls { display: flex; flex-direction: column; gap: 0.55rem; }
.ha-slider-row {
display: grid;
grid-template-columns: 90px 1fr 50px;
align-items: center;
gap: 0.6rem;
}
.ha-slider-row label {
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.75rem;
color: var(--ink-soft);
}
.ha-slider-row input[type="range"] { width: 100%; accent-color: var(--accent); }
.ha-slider-row .ha-val {
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.75rem;
color: var(--ink-soft);
text-align: right;
}
.ha-stage {
background: var(--paper-alt);
border: 1px solid var(--line);
border-radius: 10px;
padding: 1.2rem;
overflow-x: auto;
}
.ha-track {
position: relative;
height: 6px;
background: var(--line);
border-radius: 3px;
margin-bottom: 0.4rem;
}
.ha-track-fill {
position: absolute;
top: 0; left: 0; height: 100%;
border-radius: 3px;
background: var(--accent);
width: 300px;
}
.ha-ruler-label {
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.68rem;
color: var(--ink-soft);
margin-bottom: 0.9rem;
}
.ha-box-row { margin-bottom: 1.1rem; }
.ha-box-row:last-child { margin-bottom: 0; }
.ha-box-title {
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.75rem;
font-weight: 700;
color: var(--ink-soft);
margin-bottom: 0.35rem;
}
#box-content {
width: 300px;
box-sizing: content-box;
border: 5px solid red;
padding: 20px;
font-family: Georgia, "Times New Roman", serif;
font-size: 0.82rem;
color: #111;
background: #fff;
}
#box-border {
width: 300px;
box-sizing: border-box;
border: 5px solid green;
padding: 20px;
font-family: Georgia, "Times New Roman", serif;
font-size: 0.82rem;
color: #111;
background: #fff;
}
.ha-total {
font-family: "SFMono-Regular", Consolas, monospace;
font-size: 0.75rem;
color: var(--ink-soft);
margin-top: 0.35rem;
}
.ha-total b { color: var(--ink); }
</style>
</head>
<body>
<div class="infographic-boxsizing" id="ha-root">
<div class="ha-inner">
<div class="ha-layout">
<div class="ha-code-wrap">
<div class="ha-filetabs">
<button class="ha-filetab ha-tab-on" id="tab-html">index.html</button>
<button class="ha-filetab" id="tab-css">style.css</button>
</div>
<div class="ha-code">
<div class="ha-codepane ha-pane-on" id="pane-html"><<span class="ha-tag">body</span>>
<<span class="ha-tag">h3</span>>Content-box</<span class="ha-tag">h3</span>>
<<span class="ha-tag">div</span> <span class="ha-attr">class</span>=<span class="ha-str">"content-box"</span>>This box will become wider than 300px.</<span class="ha-tag">div</span>>
<<span class="ha-tag">h3</span>>Border-box</<span class="ha-tag">h3</span>>
<<span class="ha-tag">div</span> <span class="ha-attr">class</span>=<span class="ha-str">"border-box"</span>>This box will stay exactly 300px wide.</<span class="ha-tag">div</span>>
</<span class="ha-tag">body</span>></div>
<div class="ha-codepane" id="pane-css"><span class="ha-sel">.content-box</span> {
<span class="ha-prop">width</span>: <span class="ha-val">300px</span>;
<span class="ha-prop">padding</span>: <span class="ha-val">20px</span>;
<span class="ha-prop">border</span>: <span class="ha-val">5px solid red</span>;
<span class="ha-prop">box-sizing</span>: <span class="ha-val">content-box</span>;
}
<span class="ha-sel">.border-box</span> {
<span class="ha-prop">width</span>: <span class="ha-val">300px</span>;
<span class="ha-prop">padding</span>: <span class="ha-val">20px</span>;
<span class="ha-prop">border</span>: <span class="ha-val">5px solid green</span>;
<span class="ha-prop">box-sizing</span>: <span class="ha-val">border-box</span>;
}</div>
</div>
</div>
<div class="ha-controls">
<div class="ha-slider-row">
<label>padding</label>
<input type="range" id="s-padding" min="0" max="40" value="20">
<span class="ha-val" id="v-padding">20px</span>
</div>
<div class="ha-slider-row">
<label>border</label>
<input type="range" id="s-border" min="0" max="20" value="5">
<span class="ha-val" id="v-border">5px</span>
</div>
</div>
<div class="ha-stage">
<div class="ha-track"><div class="ha-track-fill"></div></div>
<div class="ha-ruler-label">300px reference line — width: 300px is set on both boxes below</div>
<div class="ha-box-row">
<div class="ha-box-title">.content-box (box-sizing: content-box)</div>
<div id="box-content">This box will become wider than 300px because padding and border are <b>added</b> outside the width.</div>
<div class="ha-total">rendered width: <b id="total-content">330px</b></div>
</div>
<div class="ha-box-row">
<div class="ha-box-title">.border-box (box-sizing: border-box)</div>
<div id="box-border">This box will stay exactly 300px wide because padding and border are <b>included</b> inside the width.</div>
<div class="ha-total">rendered width: <b id="total-border">300px</b></div>
</div>
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('ha-root');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
const tabHtml = document.getElementById('tab-html');
const tabCss = document.getElementById('tab-css');
const paneHtml = document.getElementById('pane-html');
const paneCss = document.getElementById('pane-css');
tabHtml.addEventListener('click', () => {
tabHtml.classList.add('ha-tab-on');
tabCss.classList.remove('ha-tab-on');
paneHtml.classList.add('ha-pane-on');
paneCss.classList.remove('ha-pane-on');
});
tabCss.addEventListener('click', () => {
tabCss.classList.add('ha-tab-on');
tabHtml.classList.remove('ha-tab-on');
paneCss.classList.add('ha-pane-on');
paneHtml.classList.remove('ha-pane-on');
});
})();
(function () {
const sPadding = document.getElementById('s-padding');
const sBorder = document.getElementById('s-border');
const vPadding = document.getElementById('v-padding');
const vBorder = document.getElementById('v-border');
const boxContent = document.getElementById('box-content');
const boxBorder = document.getElementById('box-border');
const totalContent = document.getElementById('total-content');
const totalBorder = document.getElementById('total-border');
function render() {
const p = +sPadding.value, b = +sBorder.value;
vPadding.textContent = p + 'px';
vBorder.textContent = b + 'px';
boxContent.style.padding = p + 'px';
boxContent.style.borderWidth = b + 'px';
boxBorder.style.padding = p + 'px';
boxBorder.style.borderWidth = b + 'px';
const contentBoxTotal = 300 + p * 2 + b * 2;
totalContent.textContent = contentBoxTotal + 'px';
totalBorder.textContent = '300px';
}
[sPadding, sBorder].forEach(el => el.addEventListener('input', render));
render();
})();
</script>
</body>
</html>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});✅ Best Practice
Always use:
/* Apply box-sizing to all elements */
* {
box-sizing: border-box;
}This way, all your boxes will behave predictably and layouts won’t break when you add padding or borders.