Development

What Is the CSS Box Model, Really?

Learn what the CSS box model actually is, why element sizing can be confusing, how margin, border, padding, and content interact, and why box-sizing changed modern CSS.

What Is the CSS Box Model, Really?

Every HTML element on a webpage is a box. The CSS box model is the set of rules browsers use to work out how big that box actually is: it wraps a box’s content in three optional layers (padding, border, and margin), and each layer adds to the total space the element takes up on the page.

That definition sounds simple, but it rarely feels that way the first time you hit it in practice.

The confusion usually starts with something like:

width: 300px;

and the discovery that the element occupies more than 300px of space. Once that happens, most developers end up here, trying to figure out where the extra pixels went.

The Four Layers of the Box

Browsers don’t treat an element as just its content. They build it out of four nested pieces:

+-------------------+
|      Margin       |
| +---------------+ |
| |    Border     | |
| | +-----------+ | |
| | |  Padding  | | |
| | | +-------+ | | |
| | | |Content| | | |
| | | +-------+ | | |
| | +-----------+ | |
| +---------------+ |
+-------------------+

The content is the actual text, image, video, or form control. Padding sits between the content and the border. The border wraps around the padding. And the margin sits outside the border, separating the element from whatever’s next to it.

Content: Where Your Dimensions Actually Apply

The content area holds the real information: text, images, videos, form controls, or whatever else the element contains. Images in particular come in different formats with different sizing behavior, covered in SVG versus PNG and vector versus raster images, but every format still occupies space as part of this layer.

Here’s the part that trips people up:

width: 300px;
height: 200px;

By default, those dimensions describe the content area only, not the full element. Everything else gets added on top.

Padding: Space That Still Belongs to the Element

Padding pushes content inward while making the element itself larger. A button with generous padding feels bigger and easier to click, even though the text inside hasn’t changed at all:

padding: 20px;

Structurally, padding sits between the content and the border:

Border
 └─ Padding
      └─ Content

Crucially, a background color applied to the element still shows through the padding. Visually, padding reads as part of the element, not a gap around it.

Border: Small Value, Real Impact

The border wraps around the padding and content, and it adds to the element’s total dimensions just as much as padding does:

border: 2px solid black;

It’s an easy layer to forget when eyeballing a layout, since a couple of pixels rarely looks like much, until it’s the reason two elements no longer line up.

Margin: Space That Belongs to No One

Margin works differently from the other three. It sits outside the border, and unlike padding, nothing about the element (not even its background) extends into it:

margin: 20px;

Margins control the gap between elements, while padding controls the gap inside them. That distinction is small on paper and responsible for a huge share of beginner CSS bugs in practice.

So Why Doesn’t Width Mean Width?

Take a fairly ordinary rule:

.box {
  width: 300px;
  padding: 20px;
  border: 5px solid black;
}

Most people expect that box to render at 300px wide. Under the default sizing model, it doesn’t: the browser adds the padding and border on top of the declared width.

300px content
+ 40px padding (20px each side)
+ 10px border (5px each side)
= 350px total width

Content-Box: The Original, Still-Default Model

That behavior above has a name: box-sizing: content-box. It’s been the browser default since CSS existed, and the math is always the same: declared width plus padding plus border equals the final rendered width. Nothing about the width you write is the final word on how wide the element ends up.

This becomes a real problem the moment percentage widths enter the picture. Two columns set to width: 50% each should fit side by side, until padding gets added to both. Then the combined width creeps past 100% and the layout breaks. Developers spent years debugging exactly this before an alternative caught on.

Border-Box: The Fix Almost Every Project Uses Now

box-sizing: border-box flips the math around: instead of adding padding and border to the declared width, it fits them inside it.

width: 300px;
padding: 20px;
border: 5px solid;
box-sizing: border-box;

Here, the total width stays exactly 300px. The content area simply shrinks to make room for the padding and border. That’s the whole appeal: the number you write is the number you get.

It’s why most projects now open their stylesheet with something like:

* {
  box-sizing: border-box;
}

One global rule, and declared widths finally match what renders.

Margin vs. Padding, One More Time

The clearest way to tell these two apart is by what happens to the background color. Set padding, and the background fills it: the color reaches all the way to the border. Set margin, and the background stops dead at the border; the space outside stays transparent no matter what color the element is.

Margin Collapsing Catches Almost Everyone Once

Vertical margins don’t always add up the way you’d expect. Put margin-bottom: 40px on one element and margin-top: 30px on the next, and most people assume 70px of separation. Browsers frequently produce 40px instead, because the larger of the two margins wins rather than the two stacking. This is called margin collapsing, and it only affects vertical margins in normal document flow. Padding never behaves this way, which is one more reason the two aren’t interchangeable.

The Box Model Doesn’t Go Away With Flexbox or Grid

Modern layout tools don’t replace any of this. Turn on display: flex and every flex item is still a box, still built from content, padding, border, and margin, still subject to the same sizing rules. CSS Grid works the same way: grid items remain boxes, and their padding and margins still shape how the layout comes together. Flexbox and Grid change how boxes get arranged on the page; they don’t change what a box is made of.

The Mistakes That Come Up Again and Again

A few problems account for most box-model bugs. Forgetting that a border adds to an element’s total size is one of the most common: it’s easy to eyeball a 2px border as negligible until it’s the reason a layout is a few pixels off. Mixing up margin and padding is another; remembering that padding is internal and margin is external clears up a surprising amount of confusion on its own. Switching sizing models partway through a project, with some elements on content-box and others on border-box, tends to produce inconsistent, hard-to-debug results. Ignoring overflow is a quieter version of the same problem, where padding and borders push an element past its container without anyone noticing until the page ships; automated visual testing with tools like Playwright tends to catch these before they reach production. And underneath most of these is the same root assumption: that a declared width is automatically a final width, which under content-box it never is.

FAQ

Why is my element bigger than the width I set? By default, CSS uses box-sizing: content-box, where the width you set only applies to the content area. Padding and border get added on top, so a 300px-wide box with 20px of padding and a 5px border actually renders at 350px. Switching to box-sizing: border-box makes the declared width include padding and border instead.

What’s the difference between margin and padding? Padding is internal spacing between the content and the border, and the element’s background color extends into it. Margin is external spacing outside the border, between the element and whatever sits next to it, and backgrounds never extend into it.

Should I use box-sizing: border-box on every project? Most developers do, usually by applying it globally with a * { box-sizing: border-box; } rule at the start of a project. It makes declared widths match rendered widths, which removes a common source of layout bugs.

What is margin collapsing? When two vertical margins meet, like the bottom margin of one element and the top margin of the next, browsers often combine them into a single margin equal to the larger of the two, rather than adding them together. This only happens with vertical margins in normal document flow; padding never behaves this way.

Does the box model still apply with Flexbox and Grid? Yes. Flexbox and Grid change how boxes are arranged on the page, but every flex or grid item is still a box made of content, padding, border, and margin, and all the usual sizing rules still apply to it.


Top