CSS Box Model
What is the Box Model?
Every HTML element on a web page is wrapped in an invisible box called the box model. The box model determines how an element is rendered, its size, and the spacing between elements.
The box model consists of four main layers, from the inside out:
- Content — The area where text, images, or other content is displayed
- Padding — The empty space between the content and the border
- Border — The edge line surrounding the padding
- Margin — The empty space outside the border that separates the element from other elements
Imagine a gift box. The gift is the content, the wrapping paper is the padding, the cardboard box is the border, and the distance from the gift box to other boxes on the shelf is the margin.
Why Is the Box Model Important?
Understanding the box model is the main foundation in CSS. Without a correct understanding, you will often run into problems such as:
- Elements whose size is not as expected
- Inconsistent spacing between elements
- Layouts that break when padding or borders are added
- Difficulty creating responsive layouts
Box Sizing
CSS has two ways of calculating an element's size, controlled by the box-sizing property:
content-box (Default)
In the default mode, the width and height properties only determine the size of the content. Padding and border are added outside of that size.
Total Width = width + padding-left + padding-right + border-left + border-right
Total Height = height + padding-top + padding-bottom + border-top + border-bottom
border-box
In this mode, the width and height properties include content + padding + border. This is more intuitive and is often recommended.
Total Width = width (already including padding and border)
Total Height = height (already including padding and border)
Visual Diagram
┌─────────────────────────── MARGIN ───────────────────────────┐
│ │
│ ┌──────────────────── BORDER ─────────────────────────┐ │
│ │ │ │
│ │ ┌───────────────── PADDING ─────────────────┐ │ │
│ │ │ │ │ │
│ │ │ CONTENT │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────┘
Code Examples
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Box Model</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
padding: 20px;
}
h1 {
margin-bottom: 20px;
color: #333;
}
.box-example {
display: flex;
gap: 30px;
flex-wrap: wrap;
}
/* Content Box (Default) */
.content-box {
width: 250px;
height: 150px;
padding: 20px;
border: 5px solid #e74c3c;
margin: 10px;
background-color: #ffeaea;
box-sizing: content-box;
}
/* Border Box */
.border-box {
width: 250px;
height: 150px;
padding: 20px;
border: 5px solid #3498db;
margin: 10px;
background-color: #eaf4fe;
box-sizing: border-box;
}
.label {
font-size: 12px;
font-weight: bold;
color: #555;
margin-top: 8px;
}
.card {
background-color: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
/* Actual size demonstration */
.size-demo {
display: flex;
gap: 40px;
flex-wrap: wrap;
margin-top: 15px;
}
.size-item {
text-align: center;
}
.size-box {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
color: white;
}
.size-box.content-mode {
width: 200px;
height: 80px;
padding: 20px;
border: 5px solid #e74c3c;
background-color: #e74c3c;
box-sizing: content-box;
}
.size-box.border-mode {
width: 200px;
height: 80px;
padding: 20px;
border: 5px solid #3498db;
background-color: #3498db;
box-sizing: border-box;
}
.total-label {
font-size: 12px;
color: #666;
margin-top: 5px;
}
/* Universal Box Sizing */
.universal-example {
background-color: #fffde7;
border: 2px dashed #f39c12;
border-radius: 6px;
padding: 15px;
margin-top: 10px;
}
</style>
</head>
<body>
<h1>CSS Box Model</h1>
<!-- Content Box vs Border Box Comparison -->
<div class="card">
<h2>Comparing Content Box vs Border Box</h2>
<p>Both boxes have a width of 250px, padding of 20px, and a border of 5px. Note the difference in their total sizes.</p>
<div class="box-example">
<div class="size-item">
<div class="box-example-content-box">
<div class="size-box content-mode">Content</div>
</div>
<div class="label">content-box</div>
<div class="total-label">Total: 250 + 40 + 10 = 300px</div>
</div>
<div class="size-item">
<div class="box-example-border-box">
<div class="size-box border-mode">Border</div>
</div>
<div class="label">border-box</div>
<div class="total-label">Total: 250px (included)</div>
</div>
</div>
</div>
<!-- Universal Box Sizing -->
<div class="card">
<h2>Universal Box Sizing</h2>
<div class="universal-example">
<code>* { box-sizing: border-box; }</code>
<p style="margin-top: 10px;">Apply border-box to all elements. This is a widely used best practice.</p>
</div>
</div>
</body>
</html>
Code Explanation
-
* { box-sizing: border-box; }— A universal selector that appliesborder-boxto all elements on the page. This ensures that width and height include padding and border. -
Reset default margin and padding —
margin: 0; padding: 0;removes the browser's default spacing so that we can control spacing consistently. -
.content-box— Explicitly appliesbox-sizing: content-box. With a width of 250px, padding of 20px (left + right = 40px), and a border of 5px (left + right = 10px), the actual total width becomes 300px. -
.border-box— Appliesbox-sizing: border-box. With the same width of 250px, the total width stays at 250px because the padding and border are already included in it. -
.card— A wrapper element with border-radius, padding, and box-shadow, to make the visualization of each section clearer. -
Box shadow —
box-shadow: 0 2px 6px rgba(0,0,0,0.1)adds a subtle shadow effect to make the card's boundaries clearer.
Everyday Use Cases
Imagine you are creating a button with this design:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
/* Without box-sizing — a common problem */
.btn-broken {
width: 200px;
padding: 15px 30px;
border: 3px solid #333;
background-color: #e74c3c;
color: white;
font-size: 16px;
cursor: pointer;
box-sizing: content-box;
}
/* With box-sizing — the correct solution */
.btn-fixed {
width: 200px;
padding: 15px 30px;
border: 3px solid #333;
background-color: #2ecc71;
color: white;
font-size: 16px;
cursor: pointer;
box-sizing: border-box;
}
.container {
padding: 20px;
font-family: Arial, sans-serif;
}
.note {
font-size: 13px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="container">
<button class="btn-broken">Broken Button</button>
<div class="note">
Actual width: 200 + 60 (padding) + 6 (border) = 266px
</div>
<br><br>
<button class="btn-fixed">Fixed Button</button>
<div class="note">
Actual width: 200px (padding and border included)
</div>
</div>
</body>
</html>
In the example above:
- The broken button uses content-box — its actual width exceeds the intended 200px because the padding and border are added on the outside.
- The correct button uses border-box — its actual width stays at 200px as defined.
This problem is very common — it is what CSS beginners often complain about: "Why is my element wider than the value I set?"
Practical Tips
Always use a box-sizing reset at the start of every project:
/* Modern CSS Reset */
*,
*::before,
*::after {
box-sizing: border-box;
}
This is the standard used by nearly all modern CSS frameworks such as Bootstrap, Tailwind CSS, and normalize.css.
Conclusion
- The box model consists of content, padding, border, and margin, from the inside out.
content-box(the default) calculates width/height based on the content only — padding and border are added on the outside.border-boxcalculates width/height including content, padding, and border — more intuitive.- Always use
box-sizing: border-boxuniversally to avoid element sizing issues. - Understanding the box model is the key to creating precise and consistent CSS layouts.