DEV Community

Snappy Tools
Snappy Tools

Posted on

The CSS Box Model: Margin, Padding, Border, and box-sizing Explained

The CSS box model is one of the first things you learn and one of the concepts you come back to most often. Understanding it properly — especially the difference between box-sizing: content-box and box-sizing: border-box — prevents a class of layout bugs that affect almost every developer at some point.

What is the box model?

Every HTML element is a rectangular box with four layers:

┌─────────────────────────────────────┐
│               MARGIN                 │  ← transparent, clears space around border
│   ┌─────────────────────────────┐   │
│   │            BORDER           │   │  ← the visible edge (if border is set)
│   │  ┌───────────────────────┐  │   │
│   │  │        PADDING        │  │   │  ← transparent, space inside border
│   │  │  ┌─────────────────┐  │  │   │
│   │  │  │     CONTENT     │  │  │   │  ← where text and child elements live
│   │  │  └─────────────────┘  │  │   │
│   │  └───────────────────────┘  │   │
│   └─────────────────────────────┘   │
└─────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode
  • Content: the area where your text, images, or child elements appear
  • Padding: transparent space between content and border
  • Border: the visible edge (optional)
  • Margin: transparent space outside the border, separating this element from others

The content-box problem

By default, width and height in CSS refer to the content area only. Padding and border are added on top of the specified size.

.box {
  width: 300px;
  padding: 20px;
  border: 2px solid black;
}
Enter fullscreen mode Exit fullscreen mode

Actual rendered width: 300 + 20 + 20 + 2 + 2 = 344px

This is box-sizing: content-box, the original CSS behaviour. It's counterintuitive: specifying width: 300px does not mean the box is 300px wide — it means the content area inside the box is 300px.

The border-box solution

box-sizing: border-box changes what width and height include:

.box {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid black;
}
Enter fullscreen mode Exit fullscreen mode

Actual rendered width: 300px — exactly.

With border-box, the padding and border are included in the specified dimensions. The content area shrinks to accommodate them: 300 - 20 - 20 - 2 - 2 = 256px content width.

Most modern CSS approaches apply border-box universally:

*, *::before, *::after {
  box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

Frameworks like Bootstrap, Tailwind, and Material UI all do this. It's the setting almost every new project should start with.

Margin

Margin is the space outside the border. It's transparent — the background colour of the element doesn't show in the margin area.

/* All sides: 20px */
margin: 20px;

/* Vertical 10px, Horizontal 20px */
margin: 10px 20px;

/* Top, Right, Bottom, Left */
margin: 10px 20px 30px 40px;

/* Individual sides */
margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;

/* Auto margins for horizontal centering */
margin: 0 auto;  /* requires a fixed width */
Enter fullscreen mode Exit fullscreen mode

Margin collapsing

Adjacent vertical margins collapse into a single margin equal to the larger of the two:

.a { margin-bottom: 20px; }
.b { margin-top: 30px; }
/* Space between a and b: 30px, not 50px */
Enter fullscreen mode Exit fullscreen mode

Margin collapsing only happens with vertical margins (top and bottom), not horizontal ones. It does not happen in flex containers or grid containers.

Padding

Padding is the space between content and border. Unlike margin, the element's background colour shows in the padding area.

padding: 20px;
padding: 10px 20px;
padding: 10px 20px 30px 40px;
padding-top: 10px;
Enter fullscreen mode Exit fullscreen mode

Click targets: padding increases the clickable area of an element without changing its visible size (when there's no visible border). This is why padding is often used on small icons and links to make them easier to tap on mobile.

Border

border: 1px solid #e2e8f0;
border: 2px dashed red;
border: none;

/* Individual sides */
border-top: 1px solid #ccc;
border-bottom: 2px solid var(--accent);

/* Individual properties */
border-width: 1px;
border-style: solid;  /* solid, dashed, dotted, double, none */
border-color: #ccc;

/* Radius */
border-radius: 8px;
border-radius: 50%;  /* circle (when width = height) */
border-radius: 4px 8px 4px 8px;  /* top-left, top-right, bottom-right, bottom-left */
Enter fullscreen mode Exit fullscreen mode

outline is similar to border but doesn't affect the box model — it draws outside the border without affecting layout or the element's dimensions. Commonly used for focus indicators.

Common layout patterns

Centring a block element:

.container {
  width: 800px;
  max-width: 100%;  /* responsive fallback
  margin: 0 auto;
}
Enter fullscreen mode Exit fullscreen mode

Equal spacing inside a card:

.card {
  padding: 24px;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}
Enter fullscreen mode Exit fullscreen mode

Separating list items:

.list-item + .list-item {
  margin-top: 8px;  /* space between items, not after the last one */
}
/* Or: */
.list-item:not(:last-child) {
  margin-bottom: 8px;
}
Enter fullscreen mode Exit fullscreen mode

Debugging with DevTools

In Chrome DevTools, click any element and open the Computed tab — you'll see the box model diagram with the actual pixel values for content, padding, border, and margin. Hovering over a CSS property in the Styles tab shows the effect on the element. Clicking the box model diagram also lets you edit values inline.


The box model is one of those fundamentals that's worth revisiting when a layout doesn't behave as expected. Most sizing bugs come down to forgetting whether padding and border are included in width, or to unexpected margin collapse. Apply box-sizing: border-box globally and most sizing surprises disappear.

Top comments (0)