Box Model

Say you have this bit of HTML:

<p>I am a paragraph of text that has a few words in it.</p>

Then you write this CSS for it:

p {
  width: 100px;
  height: 50px;
  padding: 20px;
  border: 1px solid;
}

The content ends up 142px wide, instead of the 100px you specified, and it breaks out of your element. Why is that?

The box model is a core foundation of CSS. Understanding how the box model works, how it's affected by other aspects of CSS, and importantly, how you can control it, can help you write more predictable CSS.

Understanding the box model of CSS will help you figure out why your content doesn't fit inside an element.

It's important to remember that everything displayed by CSS is a box, even if it's just some text, or has a border-radius that makes it look like a circle.

Content and sizing

Boxes have different behavior based on their display value, their set dimensions, and the content they contain. This content could be plain text, or more boxes generated by child elements. Either way, the content affects the size of the box by default.

You can control this using extrinsic sizing, or you can use intrinsic sizing to let the browser make decisions for you based on the content size.

Here's a basic demo that explains the difference:

When the box has extrinsic sizing, there's a limit to how much content you can add before it overflows out of the box. This makes the word "awesome" overflow.

The demo has the words "CSS is awesome" in a box with fixed dimensions and a thick border. Because the box has a specified width, it's extrinsically sized. This means it controls the sizing of its child content. However, the word "awesome" is too large for the box, so it overflows outside the parent box's border box (more on this later). One way to prevent this overflow is to let the box be intrinsically sized by either not setting the width, or in this case, setting the width to min-content. The min-content keyword tells the box to be only as wide as the intrinsic minimum width of its content (the word "awesome"). This lets the box fit perfectly around the text.

Here's a more complex example that shows the impact of different sizing on real content:

Extrinsic sizing lets you control the size of an element. Intrinsic sizing prevents text overflow.

Toggle intrinsic sizing on and off to see how extrinsic sizing gives you more control with extrinsic sizing and intrinsic sizing gives the content more control. To see the effects add a few sentences of text to the card. When this element has extrinsic sizing, there's a limit to how much content you can add before it overflows, but that doesn't happen when intrinsic sizing is toggled on.

By default, this element has a set width and height of 400px each. These dimensions give strict bounds to everything inside the element, which are honored unless the content is too large for the box. You can see this in action by changing the caption under the flower picture to something that exceeds the height of the box.

Key term: Overflow happens when content is too big for the box it's in. You can manage how an element handles overflow content using the overflow property.

Switching to intrinsic sizing lets the browser make decisions for you based on the box's content size. This makes overflow much less likely because the box resizes with its content.

It's important to remember that intrinsic sizing is the browser's default behavior, and it usually provides much more flexibility than extrinsic sizing.

The areas of the box model

Boxes are made up of distinct box model areas that all do a specific job.

A diagram showing the four main areas of the box model - content box, padding box, border box and margin box
The four main areas of the box model: content box, padding box, border box and margin box.

The content box is the area that the content lives in. The content can control the size of its parent, so this is usually the most variably sized area.

The padding box surrounds the content box and is the space created by the padding property. Because padding is inside the box, the box's background is visible in the space it creates. If the box has overflow rules set, such as overflow: auto or overflow: scroll, the scrollbars also occupy this space.

Scroll bars live in the padding box.

The border box surrounds the padding box, and its space is defined by the border value, which creates a visual frame for the element. The element's border edge is the limit of what you can see.

The final area, the margin box, is the space around your box, defined by the box's margin rule. Properties such as outline and box-shadow occupy this space too because they're painted on top of the element and don't affect the size of the box. Changing your box's outline-width of 200px on a box doesn't change anything inside the border edge.

A wide outline doesn't affect the size of the rest of the element.

A useful analogy

The box model is complex to understand, so here's an analogy for what you've learned so far.

Three picture frames.
The box model illustrated using physical picture frames.

In this diagram, you have three picture frames mounted next to each other on a wall. Elements of the framed image correspond to the box model as follows:

  • The content box is the artwork.
  • The padding box is the white mounting board, between the frame and the artwork.
  • The border box is the frame, providing a literal border for the artwork.
  • The margin box is the space between frames.
  • The shadow occupies the same space as the margin box.

Debug the box model

Browser DevTools provide a visualisation of a selected box's box model calculations, which can help you understand how the box model works and how it affects the website you're working on.

Try this in your own browser:

  1. Open DevTools.
  2. Select an element.
  3. Show the box model debugger.
The box model debugger for the outline demo.

Control the box model

To understand how to control the box model, you first need to understand what happens in your browser.

Every browser applies a user agent style sheet to HTML documents that defines how elements should look and behave if they don't have defined CSS. The CSS in user agent style sheets varies between browsers, but they provide sensible defaults to make content easier to read.

One property the user agent style sheet sets a box's default display. For example, in a normal flow, a <div> element's default display value is block, a <li> has a default display value of list-item, and a <span> has a default display value of inline.

An inline element has a block margin, but other elements don't respect it. With inline-block, other elements respect the block margin, but the first element keeps most of the same behaviors it had as an inline element. A block item fills the available inline space by default, whereas inline and inline-block elements are only as large as their content.

The user agent style sheet also sets box-sizing, which tells a box how to calculate its box size. By default, all elements have the following user agent style: box-sizing: content-box;. This means that when you set dimensions such as width and height, those dimensions apply to the content box. If you then set padding and border, these values are added to the content box's size.

Check your understanding

Test your knowledge of box model size impacting properties.

.my-box {
  width: 200px;
  border: 10px solid;
  padding: 20px;
}

How wide do you think .my-box will be?

260px
200px

The actual width of this box is 260px. Because the CSS uses the default box-sizing: content-box, the applied width is the width of the content, and padding and border on both sides are added to that. 200px for the content + 40px of padding + 20px of border makes a total visible width of 260px.

You can change this by specifying border-box sizing:

.my-box {
  box-sizing: border-box;
    width: 200px;
    border: 10px solid;
    padding: 20px;
}

This alternative box model tells CSS to apply the width to the border box instead of the content box. This means our border and padding get pushed in, so when you set .my-box to be 200px wide, it actually renders at 200px wide.

Check out how this works in the following interactive demo. When you toggle the box-sizing value, the blue area shows which CSS is being applied inside the box.

Compare the effects of content-box and border-box sizing.
*,
*::before,
*::after {
  box-sizing: border-box;
}

This CSS rule selects every element in the document and every ::before and ::after pseudo element and applies box-sizing: border-box. This means that every element now uses this alternative box model.

Because the alternative box model can be more predictable, developers often add this rule to resets and normalizers, like this one.

Resources

User agent stylesheets