The box model
Every element is a box of content, padding, border and margin. box-sizing decides whether width means the content or the whole box.
Four layers per box
The browser draws every element as a rectangle with four layers, from the inside out:
- content: the text or image itself
- padding: space inside the border, coloured by the background
- border: the line around it
- margin: space outside the border, always see-through, pushing other boxes away
.card {
padding: 16px;
border: 2px solid #333;
margin: 24px;
}Padding makes a button feel roomier. Margin moves it away from its neighbours. Open your browser's dev tools, inspect any element and you will see these four layers drawn as nested boxes.
What width really measures
By default width: 200px sets only the content. Padding and border are added on top, so a 200px card with 20px padding and a 5px border is really 250px wide. That surprise breaks layouts all the time.
* {
box-sizing: border-box;
}With border-box, width means the whole box including padding and border, and the content shrinks to fit. Most sites put that rule at the top of their CSS.
Run it: two cards, same width
Run it, then change one thing and run it again.
<style>
.card {
width: 200px;
padding: 20px;
border: 5px solid #46a9b3;
margin: 12px 0;
background: #eef7f8;
}
.fixed {
box-sizing: border-box;
}
</style>
<div class="card">content-box: I am wider than 200px</div>
<div class="card fixed">border-box: I am exactly 200px</div>
<script>
for (const card of document.querySelectorAll(".card")) {
console.log(card.textContent.split(":")[0], "is", card.offsetWidth + "px wide");
}
</script>
A card that spills over
The profile card should be exactly 300px wide on screen, so it fits the 300px column. It comes out 350px. Fix it with one CSS line, without changing the width, padding or border.
<style>
.column { width: 300px; background: #ddd; }
.profile {
width: 300px;
padding: 20px;
border: 5px solid #222;
}
</style>
<div class="column">
<div class="profile">Zara, level 12</div>
</div>