Start.dev
Back to blog

The CSS Box Model Explained, With Visual Examples

Learn the CSS box model with clear diagrams and code: content, padding, border, and margin, plus box-sizing, margin collapse, and DevTools tips.

Ariel Weinberger
Ariel Weinberger · 8 min read

You set a div to width: 300px, add some padding, and suddenly it's wider than 300 pixels and your layout breaks. Or you add margin between two paragraphs and the gap is smaller than you expected. Neither is a bug. Both come from the CSS box model, the rule that governs how every element on a web page gets its size and space.

Once the box model clicks, a lot of CSS confusion goes away. In this guide you'll learn the four parts of a box, how the browser adds them up, and the handful of gotchas that trip up almost every beginner. If you'd rather learn it hands-on, the lesson What Is The Box Model (opens in a new tab) covers the same ground with exercises you can run as you go.

Everything on a web page is a box

Every HTML element, whether a heading, a button, an image, or a link, is rendered as a rectangular box. Even if a design looks round or irregular, there's a rectangle underneath. (A circular avatar is a square box with border-radius applied.)

Each box has four layers, from the inside out:

  1. Content: the text, image, or child elements
  2. Padding: breathing room between the content and the border
  3. Border: a line (visible or not) around the padding
  4. Margin: empty space outside the border, separating this box from its neighbors

Here's the classic diagram:

┌──────────────────────────────────────────────┐
│                   MARGIN                     │
│   ┌──────────────────────────────────────┐   │
│   │               BORDER                 │   │
│   │   ┌──────────────────────────────┐   │   │
│   │   │           PADDING            │   │   │
│   │   │   ┌──────────────────────┐   │   │   │
│   │   │   │                      │   │   │   │
│   │   │   │       CONTENT        │   │   │   │
│   │   │   │                      │   │   │   │
│   │   │   └──────────────────────┘   │   │   │
│   │   └──────────────────────────────┘   │   │
│   └──────────────────────────────────────┘   │
└──────────────────────────────────────────────┘

A useful mental picture is a framed painting hung on a wall. The painting is the content. The mat around it is the padding. The frame is the border. The space between this frame and the next one on the wall is the margin.

The four layers in code

Here's a single box using all four layers:

.card {
  width: 300px;              /* content width */
  padding: 20px;             /* space inside the border */
  border: 5px solid #333;    /* the frame */
  margin: 30px;              /* space outside the border */
  background: #f4f1ea;
}

A few things worth noticing:

  • Background color fills the content and padding, and stops at the border (technically it extends under the border, but you rarely notice). It never fills the margin. Margin is always transparent.
  • Padding is inside, margin is outside. If you want the clickable or colored area of a button to grow, use padding. If you want to push the button away from other things, use margin. The lessons on Padding (opens in a new tab) and Margin (opens in a new tab) let you practice each one on its own.
  • Borders take up space. Even a 1px border adds to the box's total size, which brings us to the part that surprises people. (Borders (opens in a new tab) covers border width, style, and color.)

How big is the box, really?

By default, the width and height properties set the size of the content area only. Padding and border are added on top of that. If you want to practice setting sizes before going further, see Width And Height (opens in a new tab).

So for the .card above, the real horizontal footprint is:

content width      300px
+ padding (20 × 2)  40px
+ border  (5 × 2)   10px
─────────────────────────
visible box width  350px
+ margin  (30 × 2)  60px
─────────────────────────
space on the page  410px

You asked for 300px and got a box that's 350px wide, taking up 410px of room. This is the content-box model, the browser default, and it's the reason layouts that look right on paper overflow their containers. The lesson Box Sizing (opens in a new tab) explains how the two sizing models differ.

The fix: box-sizing: border-box

This is why two columns set to width: 50% with padding and a border can end up wider than their container and wrap onto a second line. The box-sizing property fixes it by changing how width and height are calculated.

.column {
  box-sizing: border-box;
  width: 50%;
  padding: 20px;
  border: 2px solid black;
}

With border-box, the width you set includes padding and border. The content area shrinks to make room instead of the whole box growing, so both columns fit.

Most developers prefer border-box because the numbers behave the way you'd naturally expect. It's so common that nearly every modern project starts with this reset:

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

Put that at the top of your stylesheet and you'll rarely have to do box-model arithmetic again. You can try the switch yourself in Border Box (opens in a new tab).

Padding and margin shorthand

You'll often want different values on different sides. The shorthand reads clockwise starting at the top:

.box { padding: 10px 20px 10px 20px; } /* top right bottom left */
.box { padding: 10px 20px; }           /* top/bottom, left/right */
.box { padding: 10px; }                /* all four sides */

A memory trick for the four-value form: TRouBLe (Top, Right, Bottom, Left). Margin and border-width use the exact same pattern.

Margin has special behaviors

Padding is straightforward. Margin has a couple of quirks worth learning early, and the Margin (opens in a new tab) lesson is a good companion for this section.

Margins can be auto

On a block element with a set width, margin: 0 auto splits the leftover horizontal space evenly on both sides, which centers it. It's the oldest trick for centering a page layout, and it still works. For vertical centering and the other methods, see How to center a div: every method, and when to use it.

Vertical margins collapse

This is the one that causes the most head-scratching. When two vertical margins touch, the browser doesn't add them together. It uses the larger of the two.

.first  { margin-bottom: 40px; }
.second { margin-top: 20px; }

You might expect a 60px gap. You get 40px.

┌─────────────┐
│    first    │
└─────────────┘
      ↕ 40px   ← not 60px; the margins collapse
┌─────────────┐
│   second    │
└─────────────┘

A few details about collapsing:

  • It only happens vertically. Left and right margins never collapse.
  • It can also happen between a parent and its first or last child if nothing (no padding, border, or content) separates their margins.
  • It does not happen on flex or grid items, or on elements with overflow set to something other than visible.

If margin collapse is bothering you, one common workaround is to use gap in a flex or grid container instead of margins, or to put spacing on one side only (for example, always margin-bottom, never margin-top).

Inline vs. block boxes

Not every box behaves the same. The display property changes how the box model applies. If this part is new to you, start with What Is Display (opens in a new tab) and then Block Inline And Inline Block (opens in a new tab).

displayStarts on new line?Respects width/height?Vertical padding/margin
block (div, p, h1)YesYesPushes other content away
inline (span, a, strong)NoNoPadding paints, but doesn't push neighbors; vertical margin is ignored
inline-blockNoYesBehaves like a block, but sits in the text flow

Seeing the box model in your browser

You don't have to imagine any of this. Right-click any element, choose Inspect, and look for the box model diagram in the Computed tab (Chrome and Edge) or the Layout tab (Firefox). Hover over it and the browser highlights content, padding, border, and margin on the page, so you can usually spot the culprit behind a stray gap in seconds. You can even edit the numbers live to test fixes before touching your code.

A complete worked example

Let's put it all together by building a simple, well-behaved card.

<div class="card">
  <h2>Box Model Basics</h2>
  <p>Content, padding, border, margin. That's the whole thing.</p>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}
 
.card {
  width: 320px;
  padding: 24px;
  border: 2px solid #2b2b2b;
  border-radius: 8px;
  margin: 32px auto;
  background: #fffaf0;
}
 
.card h2 {
  margin: 0 0 12px;   /* remove default top margin, add space below */
}
 
.card p {
  margin: 0;
}

What's happening here:

  • border-box means the card is exactly 320px wide, with 24px padding and a 2px border carved out of that. The content area is 320 − 48 − 4 = 268px.
  • margin: 32px auto puts 32px above and below, and centers the card horizontally.
  • Headings and paragraphs come with default browser margins. Resetting them inside the card gives you precise control over the spacing, instead of fighting the defaults.

Quick recap

  • Every element is a box with four layers: content, padding, border, margin.
  • Padding is inside the border and takes the background color. Margin is outside and is always transparent.
  • By default (content-box), width and height apply to the content only, so padding and border make the box bigger.
  • Set box-sizing: border-box globally so the width you write is the width you get.
  • Vertical margins collapse. Horizontal ones don't.
  • Use your browser's DevTools to see the box model on any element, live.

Practice exercise

The fastest way to lock this in is to break things on purpose:

  1. Create a div with width: 200px; padding: 30px; border: 10px solid; margin: 20px; and read its computed size in DevTools. Does it match the math?
  2. Add box-sizing: border-box and watch the total size change.
  3. Stack two of these divs with margin-bottom: 50px on one and margin-top: 30px on the other, and measure the gap.

When you're done, test yourself with Box Model Knowledge Check (opens in a new tab).

Where to go next

The box model is the foundation for almost everything else in CSS layout. Once you're comfortable with it, the natural next steps are Flexbox for one-dimensional layouts (start with What Is Flexbox (opens in a new tab)), CSS Grid for two-dimensional ones (What Is Grid (opens in a new tab)), and positioning (What Is Positioning (opens in a new tab)). Each of them still builds on the boxes you just learned, so the time you spend here pays off in every layout you build from now on. Not sure which of the first two to pick? Read Flexbox vs Grid: which to use, and when.

If you're curious how this looks with a utility-first approach, the box model works exactly the same way in Tailwind CSS. Classes like p-4, m-4, and border just set the same padding, margin, and border properties you've seen here, and Tailwind turns on border-box sizing by default. The Padding (opens in a new tab) and Margin (opens in a new tab) lessons in Tailwind CSS Basics (opens in a new tab) show how that maps onto what you just learned. Not sure whether to learn Tailwind before or after plain CSS? Our post Tailwind CSS vs CSS: should beginners learn Tailwind first? walks through that decision.

Ready to keep going? These two courses cover the full path, from your first CSS rule to utility-first styling:

Level up your coding skills

Jump into interactive courses and start building real-world projects.

Start learning

Related posts

Learn how to center a div in CSS with Flexbox, Grid, margin auto, text-align, absolute positioning and Tailwind, and which method to pick for each situation.
Ariel Weinberger
Ariel Weinberger · 6 min read
Should beginners learn Tailwind or plain CSS first? See the same card built both ways, what Tailwind assumes you know, and a learning order that works.
Ariel Weinberger
Ariel Weinberger · 5 min read
Flexbox or CSS Grid? Learn the one-dimensional vs two-dimensional rule, see both build the same layout, and get a quick way to pick the right one.
Ariel Weinberger
Ariel Weinberger · 6 min read