Chapter 13 Intermediate 40 min min read Updated 2026-04-11

The Box Model - Margin, Border, Padding

Practice Questions →

In This Chapter

What Is It?

What Is the Box Model?

Every HTML element is rendered as a rectangular box. That box has four layers from the inside out:

  1. Content -- the actual text, image, or child elements
  2. Padding -- transparent space around the content, inside the border
  3. Border -- a line drawn around the padding
  4. Margin -- transparent space outside the border, pushing other elements away

Understanding the box model is non-negotiable. Almost every layout bug beginners run into -- 'why is my element wider than I expected?', 'why is there extra space here?', 'why won't my div center?' -- is a box model issue.

/* A box with all four parts */
.card {
  width: 300px;
  padding: 20px;
  border: 2px solid #a855f7;
  margin: 16px;
}

Why Does It Matter?

Why Is the Box Model So Important?

1. Every Layout Problem Is a Box Problem

Elements not lining up? Too much space? Card wider than expected? These are almost always box model issues. Once you truly understand how content, padding, border, and margin interact, layout becomes intuitive instead of mysterious.

2. content-box vs border-box Changes Everything

By default, width: 300px means the content is 300px. Padding and border are added on top, making the total bigger. This is counter-intuitive. Almost every modern project uses box-sizing: border-box so that width means 'total box width'. This is a one-line reset that saves hours of debugging.

3. Cards, Buttons, and Containers All Use It

A card is just a box with padding, border-radius, and box-shadow. A button is a box with padding and background. A container is a box with max-width and auto margins. You will use the box model in literally every component you build.

4. Margin Collapsing Trips Up Everyone

There is one weird rule: vertical margins between adjacent blocks collapse into the larger one. Beginners lose hours to this. Once you know about it, you know how to avoid it.

Detailed Explanation

Detailed Explanation

1. Inspecting the Box Model

Right-click any element and choose 'Inspect'. In DevTools, look for the box model diagram -- it shows exactly how big the content, padding, border, and margin are. This is the fastest way to debug layout bugs.

2. content-box (Default) vs border-box

This is the single most important concept in CSS layout.

/* content-box (default) */
.box1 {
  box-sizing: content-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
/* Actual rendered width = 200 + 20 + 20 + 5 + 5 = 250px */

/* border-box */
.box2 {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
/* Actual rendered width = 200px (padding and border subtract from content) */

With content-box, width means 'the content area'. Padding and border get added on top.

With border-box, width means 'the total box'. Padding and border eat into that total.

3. The Universal Reset

Almost every modern stylesheet starts with this:

*, *::before, *::after {
  box-sizing: border-box;
}

This applies border-box to every element and pseudo-element. Now width actually means width. Problem solved for the entire project.

4. padding Shorthand

padding shorthand accepts 1, 2, 3, or 4 values.

padding: 20px;              /* all four sides */
padding: 10px 20px;         /* top/bottom | left/right */
padding: 10px 20px 30px;    /* top | left/right | bottom */
padding: 10px 20px 30px 40px; /* top | right | bottom | left (clockwise) */

/* Or individual sides */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;

5. border

border shorthand: width style color. Border styles: solid, dashed, dotted, double, groove, ridge, inset, outset, none.

border: 2px solid #a855f7;
border: 1px dashed gray;
border: 4px double red;

/* Individual sides */
border-top: 3px solid black;
border-bottom: 1px solid #eee;

/* Just one property */
border-color: red;
border-width: 2px;
border-style: dotted;

6. border-radius

Rounds corners. Works on any box.

border-radius: 8px;       /* All four corners */
border-radius: 50%;       /* Circle (if width = height) */
border-radius: 12px 4px;  /* top-left+bottom-right | top-right+bottom-left */
border-radius: 20px 0 20px 0;  /* each corner, clockwise from top-left */

/* Individual corners */
border-top-left-radius: 16px;
border-bottom-right-radius: 16px;

/* Elliptical corners */
border-radius: 100px / 50px;  /* horizontal radius / vertical radius */

7. margin Shorthand

Same 1/2/3/4 value syntax as padding.

margin: 20px;
margin: 10px 20px;
margin: 10px 20px 30px 40px;

margin-top: 20px;
margin-bottom: 20px;

8. margin: 0 auto -- Centering

To center a block element horizontally, set margin: 0 auto and give it a width. The browser splits the remaining horizontal space equally.

.container {
  max-width: 1200px;
  margin: 0 auto; /* top-bottom 0, left-right auto */
}

9. Negative Margins

Margins can be negative. This pulls the element in the opposite direction or onto a neighbor.

.overlap {
  margin-top: -20px; /* pulls up, overlapping the element above */
}

10. Margin Collapsing (Important!)

When two vertical margins touch, they collapse into the larger one instead of adding up. This ONLY happens for vertical (top/bottom) margins between block elements.

<style>
  h1 { margin-bottom: 30px; }
  p  { margin-top: 20px; }
</style>
<h1>Title</h1>
<p>Paragraph</p>

/* You might expect 30 + 20 = 50px of space. */
/* Actual space = 30px (the larger of the two). This is margin collapse. */

Rules:

  • Only vertical margins collapse (not horizontal)
  • Only between adjacent block elements (not flex/grid children)
  • Only touching margins (no border, padding, or content between them)

To prevent collapsing: add padding, a border, or use flexbox/grid layouts.

11. padding Shorthand Examples

.btn { padding: 12px 24px; }   /* classic button: 12px vertical, 24px horizontal */
.card { padding: 24px; }       /* uniform card padding */

12. outline vs border

outline is similar to border but:

  • It does NOT take up space (draws on top, does not shift layout)
  • It goes around the border, not inside it
  • It cannot have different values per side
  • It is used for focus rings (accessibility)
button:focus {
  outline: 3px solid #a855f7;
  outline-offset: 2px;
}

13. box-shadow

Syntax: x-offset y-offset blur spread color. Creates a drop shadow.

box-shadow: 0 4px 6px rgba(0,0,0,0.1);        /* subtle lift */
box-shadow: 0 10px 30px rgba(0,0,0,0.15);     /* bigger lift */
box-shadow: 0 20px 60px rgba(168, 85, 247, 0.3); /* purple glow */

/* Inset shadow (inside the box) */
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);

/* Multiple shadows stacked */
box-shadow:
  0 1px 2px rgba(0,0,0,0.08),
  0 8px 24px rgba(0,0,0,0.12);

x and y are the offsets (positive down/right), blur softens the edge, spread grows or shrinks the shadow uniformly.

Code Examples

Visualizing the Box Model
<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; padding: 40px; background: #f3f4f6; }
    .box {
      width: 200px;
      padding: 20px;
      border: 6px solid #a855f7;
      margin: 30px;
      background: #fef3c7;
      color: #1a1a2e;
      text-align: center;
    }
    .label { color: #6b7280; font-size: 14px; }
  </style>
</head>
<body>
  <p class="label">content-box (default). Actual width = 200 + 20 + 20 + 6 + 6 = 252px.</p>
  <div class="box">
    This is the content. Around it is 20px padding, then a 6px purple border, then 30px margin pushing neighbors away.
  </div>
  <p class="label">Open DevTools and inspect the box to see the box model layers.</p>
</body>
</html>
This shows a classic box with all four parts: content (the text), padding (amber space around the text), border (thick purple line), and margin (whitespace outside pushing the paragraphs away). Use DevTools' inspect tool to see each layer highlighted in different colors.
A yellow box with a thick purple border and space around it. The content inside is centered text.
content-box vs border-box Comparison
<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; padding: 40px; }
    .box {
      width: 300px;
      padding: 20px;
      border: 5px solid #a855f7;
      margin-bottom: 16px;
      background: #f3f4f6;
    }
    .content-box { box-sizing: content-box; }
    .border-box  { box-sizing: border-box; }
    .ruler { width: 350px; border-top: 2px dashed #9ca3af; margin: 8px 0 24px; font-size: 12px; color: #6b7280; text-align: right; }
  </style>
</head>
<body>
  <h2>Both have width: 300px</h2>
  <p>By Priya Sharma. Notice the difference in actual rendered width.</p>

  <div class="box content-box">content-box: width=300px. Actual total = 300 + 20 + 20 + 5 + 5 = 350px</div>
  <div class="ruler">350px</div>

  <div class="box border-box">border-box: width=300px. Actual total = 300px (padding and border eat into the 300)</div>
  <div class="ruler">300px</div>
</body>
</html>
Both boxes declare width: 300px, but the first one (content-box) is actually 350px wide because padding and border are added. The second one (border-box) is exactly 300px because padding and border are subtracted from the content area. This is why nearly every project uses border-box.
Two gray boxes. The first is visibly wider than the second despite both declaring the same width, because of different box-sizing values.
Card with Border Radius and Shadow
<!DOCTYPE html>
<html>
<head>
  <style>
    * { box-sizing: border-box; }
    body { font-family: Arial, sans-serif; background: #f9fafb; padding: 60px; display: flex; justify-content: center; }
    .card {
      width: 320px;
      background: white;
      padding: 28px;
      border-radius: 16px;
      box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08), 0 4px 10px rgba(0, 0, 0, 0.04);
    }
    .avatar {
      width: 80px;
      height: 80px;
      border-radius: 50%;
      background: linear-gradient(135deg, #a855f7, #06b6d4);
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 32px;
      font-weight: bold;
      margin: 0 auto 16px;
    }
    h3 { margin: 0 0 4px; text-align: center; color: #1a1a2e; }
    .role { text-align: center; color: #6b7280; font-size: 14px; margin: 0 0 16px; }
    .bio { color: #4b5563; line-height: 1.6; font-size: 14px; margin: 0 0 16px; }
    .btn {
      display: block;
      width: 100%;
      padding: 12px;
      border: none;
      border-radius: 8px;
      background: #a855f7;
      color: white;
      font-size: 14px;
      font-weight: 600;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="card">
    <div class="avatar">AR</div>
    <h3>Aarav Reddy</h3>
    <p class="role">Full Stack Developer</p>
    <p class="bio">Loves building things for the web. Currently learning advanced CSS and React. Cricket fan. From Hyderabad.</p>
    <button class="btn">Follow</button>
  </div>
</body>
</html>
A modern card. Notice the * { box-sizing: border-box } reset at the top. The avatar uses border-radius: 50% to become a circle. The card uses two stacked box-shadows for a realistic depth effect. Padding gives breathing room inside.
A clean white profile card with a gradient circular avatar, centered name and role, description, and a full-width purple button.
Centering with margin: 0 auto
<!DOCTYPE html>
<html>
<head>
  <style>
    * { box-sizing: border-box; }
    body { font-family: Arial, sans-serif; background: #e5e7eb; padding: 40px 0; margin: 0; }
    .container {
      max-width: 800px;
      margin: 0 auto;
      background: white;
      padding: 30px 40px;
      border-radius: 12px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
    }
    h1 { color: #a855f7; margin: 0 0 16px; }
    p { line-height: 1.6; color: #4b5563; margin: 0 0 12px; }
    .inner {
      max-width: 400px;
      margin: 24px auto;
      padding: 16px;
      background: #f3f4f6;
      border-radius: 8px;
      text-align: center;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>Centered Container</h1>
    <p>This container has max-width: 800px and margin: 0 auto. The browser splits the leftover horizontal space equally, centering the container regardless of viewport width. This is the classic way to create a centered page layout without flexbox or grid.</p>
    <div class="inner">
      <strong>Inner box also centered</strong><br>
      max-width: 400px; margin: 24px auto;
    </div>
    <p>By Kavya Patel. Resize the window to see the container stay centered.</p>
  </div>
</body>
</html>
margin: 0 auto is the classic block-centering trick. 'auto' on left and right tells the browser to distribute leftover horizontal space equally. It only works when the element has an explicit width (or max-width).
A page with an 800px wide white container centered horizontally, containing a heading, paragraphs, and a smaller nested centered box.
Margin Collapse Demo
<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: Arial, sans-serif; padding: 20px; background: #f9fafb; }
    .note { color: #6b7280; font-size: 13px; }
    .box {
      background: #fef3c7;
      padding: 8px 16px;
      border: 1px solid #f59e0b;
    }
    .a { margin-bottom: 40px; }
    .b { margin-top: 30px; }
    .fix-wrap { border: 2px dashed #a855f7; padding: 1px; margin-top: 30px; }
    .fix-wrap .box { margin: 0; }
  </style>
</head>
<body>
  <h2>Margin Collapse</h2>
  <p class="note">Box A has margin-bottom: 40px. Box B has margin-top: 30px. You might expect 70px of space between them. Actual space: 40px (the larger one wins).</p>
  <div class="box a">Box A (margin-bottom 40px)</div>
  <div class="box b">Box B (margin-top 30px)</div>
  <p class="note">Adding padding or a border between them prevents the collapse. Here we wrap Box B in a purple-bordered container that forces its margin to act independently:</p>
  <div class="box a">Another Box A</div>
  <div class="fix-wrap">
    <div class="box">Wrapped Box -- no collapse with the previous one.</div>
  </div>
  <p class="note">By Ishaan. Margin collapse is a weird CSS rule that trips up beginners. It only affects vertical margins between block elements.</p>
</body>
</html>
The first example shows margin collapse: 40px + 30px = 40px total (not 70). The second example prevents it by wrapping the second box in an element with a border, so the margins no longer touch directly and cannot collapse.
Two examples stacked: the first shows collapsed margins (smaller gap than expected), the second uses a bordered wrapper to prevent the collapse.
Box Shadows Showcase
<!DOCTYPE html>
<html>
<head>
  <style>
    * { box-sizing: border-box; }
    body { font-family: Arial, sans-serif; padding: 40px; background: #f3f4f6; display: flex; flex-wrap: wrap; gap: 30px; justify-content: center; }
    .card {
      width: 180px;
      height: 180px;
      background: white;
      border-radius: 12px;
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      padding: 16px;
      color: #1a1a2e;
      font-size: 13px;
    }
    .s1 { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); }
    .s2 { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); }
    .s3 { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); }
    .s4 { box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2); }
    .glow { box-shadow: 0 15px 40px rgba(168, 85, 247, 0.4); }
    .inset { box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.1); background: #f9fafb; }
    .multi {
      box-shadow:
        0 1px 2px rgba(0, 0, 0, 0.08),
        0 8px 16px rgba(0, 0, 0, 0.1),
        0 24px 48px rgba(0, 0, 0, 0.08);
    }
  </style>
</head>
<body>
  <div class="card s1">1 Subtle</div>
  <div class="card s2">2 Small</div>
  <div class="card s3">3 Medium</div>
  <div class="card s4">4 Large</div>
  <div class="card glow">5 Purple Glow</div>
  <div class="card inset">6 Inset</div>
  <div class="card multi">7 Multi-layer (realistic)</div>
</body>
</html>
Seven different shadow styles: from barely visible to large dramatic shadows, colored glows, inset (sunken) shadows, and multi-layered shadows that feel more realistic. Stacking multiple shadows with different blurs produces the most lifelike depth.
A grid of white cards, each with a different shadow style -- from barely-there to bold, colored, inset, and layered.

Common Mistakes

Forgetting box-sizing: border-box

.card {
  width: 100%;
  padding: 20px;
  border: 2px solid black;
}
/* Card overflows its parent by 44px */
width: 100% means the content is 100%. Padding and border add 44px extra, causing the card to overflow.
*, *::before, *::after { box-sizing: border-box; }

.card {
  width: 100%;
  padding: 20px;
  border: 2px solid black;
}
/* Now width: 100% includes padding and border. No overflow. */
The universal box-sizing reset at the top of your CSS is non-negotiable in modern projects. It makes width and height mean what you expect: the total box size.

Expecting Vertical Margins to Add

h1 { margin-bottom: 30px; }
p  { margin-top: 30px; }
/* Expected 60px gap, actual 30px */
Vertical margins between adjacent block elements collapse into the larger one, not added together.
/* Option 1: Use only one margin direction */
h1 { margin-bottom: 60px; }
p  { margin-top: 0; }

/* Option 2: Use padding instead */
/* Option 3: Use flex or grid with gap, which do not collapse */
Margin collapse only happens with vertical margins on block elements. Using gap in flex/grid containers avoids it entirely. A common modern approach is to only set margin in one direction.

Using margin: 0 auto Without a Width

.container {
  margin: 0 auto;
  /* No width or max-width set */
}
/* Does not center -- container is full width already */
Without a width or max-width, the container already fills its parent. Auto margins have nothing to distribute, so nothing changes.
.container {
  max-width: 1200px;
  margin: 0 auto;
}
margin: 0 auto only centers when there is leftover horizontal space to distribute. You need an explicit width or max-width smaller than the parent.

Confusing outline with border

button:focus {
  border: 2px solid blue;
}
/* The button shifts 2px when focused because the border takes up space */
Adding a border changes the element's size, making it shift. This looks jarring during keyboard focus.
button:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}
outline is drawn outside the border and does NOT take up space. The button does not shift. Use outline for focus rings (keyboard accessibility). Never remove outline without providing an alternative focus indicator.

Summary

  • Every element is a box with four layers: content (inside), padding (around content), border (around padding), margin (outside border pushing other elements away).
  • box-sizing: content-box (default) means width refers to the content only. Padding and border add to the total. This is counter-intuitive and causes bugs.
  • box-sizing: border-box means width refers to the total box. Padding and border subtract from the content area. Almost every modern project uses this via a universal reset: *, *::before, *::after { box-sizing: border-box; }.
  • padding and margin shorthands accept 1 to 4 values: all sides / vertical+horizontal / top+horizontal+bottom / top+right+bottom+left (clockwise).
  • margin: 0 auto horizontally centers a block element -- but only when it has a defined width or max-width smaller than its parent.
  • Vertical margins between adjacent block elements collapse into the larger one (margin collapse). Add padding, a border, or use flex/grid to prevent it.
  • border shorthand: width style color (e.g. 2px solid #a855f7). Individual sides: border-top, border-bottom, border-left, border-right.
  • border-radius rounds corners. Use 50% on a square to make a circle. Individual corner properties: border-top-left-radius, border-bottom-right-radius, etc.
  • outline is drawn around the border and does NOT take up space. Use it for focus rings. Do not remove focus outlines without providing an alternative.
  • box-shadow: x-offset y-offset blur spread color. Stack multiple shadows for realistic depth. Use inset for interior shadows. Use rgba with low alpha for subtle lifts.

Ready to Practice?

Test your understanding with 50+ practice questions on this topic.

Go to Practice Questions

Want to learn web development with a live mentor?

Explore our Frontend Masterclass