CSS Box Model, box-sizing, and border-box

Look familiar?

CSS is integral to understanding web design and the CSS Box Model is integral to understanding CSS. Those already familiar with the diagram above may want skip to the bottom of this post where I’ll share something I recently learned that might be new information for others as well. But for everyone’s sake, let’s break down the CSS Box Model and provide some helpful context.

Every single CSS element is represented by a box like the one above. A text box, an image, a button, a div, a select…everything. We can verify this by using our browser’s DevTools — right click on any web page and select “inspect” and they’ll pop right up. Click on the arrow and box in the upper-left section of this new pop-out and hover your mouse over anything on the web page to see some color-coded sizing and spacing info. You can also click on elements to get more detail, but I’ll mostly be using hover to display our changes.

The box returns

Now that we’ve verified their existence, we can start to explore how to alter the size of an element’s content area, padding area, border area, and margin area. We’ll return to the inspect view regularly in this article to verify that our changes have taken effect.

Located in the middle of the box and highlighted in blue, the content area can be thought of as the space allotted for your text. Let’s put together a sample element using the following code HTML and CSS.

HTML:

<html>
<body>
<div class="div3">Hooray!</div> </body>
</html>

CSS:

.div3 {
width: 100px;
height: 50px;
padding: 10px;
margin: 10px;
border: 1px solid red;
}
All four layers are included for clarity, but we’re just focusing on the content area (blue) right now

Our content area size is determined by the width and height attributes in our CSS. What happens if we change the numbers? The size of the Content changes!

Updated CSS:

.div3 {
width: 200px;
height: 25px;

padding: 10px;
margin: 10px;
border: 1px solid red;
}

Updated Element:

Longer width, shorter height

The shape of our entire box changed because this code sets height and width of the content area as absolute and makes everything else (padding, margin, and border) relative to the content. We’ll see later that it’s possible to make a different area absolute so that changing height and width have a different effect.

The padding area is the space between content area and border — changing the padding size will generally increase the size of your text container:

Updated CSS:

.div3 {
width: 200px;
height: 25px;
padding: 30px;
margin: 10px;
border: 1px solid red;
}
More green!

The content area remained the same, but the box grew because it needed to account for 30 pixels of padding on each side. Border and margin area work the same way:

.div3 {
width: 200px;
height: 25px;
padding: 10px;
margin: 30px;
border: 5px solid red;

}
We reset padding to 10px, but increased margin and border size

That thick red line is a 5 pixel border and all the orange is our margin area. While padding separates the content area from the border, margin separates elements from each other. With a 30 pixel margin, no other text box can enter this zone (unless we overwrite the CSS with some more code).

Remember how I said that height and width don’t always directly relate to the content area? An element’s box-sizing attribute is set to content-box by default, so the true area of an element will be the result of the height times width, plus the padding, plus the border. This isn’t quite intuitive — if I write height: 100px, I sort of expect the height of my element to be 100 pixels. So what if we changed the setting of the box-sizing attribute?

If you add box-sizing: border-box; to your element’s CSS, you’ll be able to absolutely declare the size of the box, content, padding, and border included. (Note in the following code that I also reverted the height and width to their original values):

.div3 {
width: 100px;
height: 50px;

padding: 10px;
border: 1px solid red;
box-sizing: border-box;
}
The padding and border are the same as in our initial example, but the content area has shrunk to account for our declaration of border-box sizing.

Now, rather than increasing the box size, changing the padding will move the content around inside the box:

.div3 {
width: 100px;
height: 50px;
padding: 20px;
border: 1px solid red;
box-sizing: border-box;
}
The content area has almost disappeared!

We can see a few things here. First, the text moved further down and to the right. This is because the padding pushed the start of our content area deeper into the box when it increased in size. Since we’ve declared that box-sizing is related to the border, the content has become the flexible element, adjusting to meet the numbers we’ve declared elsewhere.

We can also see that the content area is smaller than the actual text — keep this in mind as it can sometimes cause unexpected behavior in CSS. In fact, since we know that padding is, by default, applied evenly on all sides, we can shrink the content area’s box down to nothing if we change our padding to more than half of one of our border-box’s dimensions.

.div3 {
width: 100px;
height: 50px;
padding: 30px;
border: 1px solid red;
box-sizing: border-box;
}
Is that box…bigger? Yes it is.

Here’s the final lesson: you can overwrite your dimensions even when using box-sizing. This CSS results in a box with a height of 60 pixels because it has to account for 30 pixels of padding both above and below the (imperceptible, but existent) content area. CSS, like all code, works best when you test early and often. You never know what you might learn!

Resources:

Solutions Engineer