Piccalilli supports Black Lives Matter. Code is always political.

How CSS box sizing works

Pretty much everything in CSS is a box, so let’s learn how sizing them works.

If there’s ever one really important thing to remember when writing CSS: it’s that pretty much everything is a box. Regardless of how an element looks visually, it’s still a box.

A circle that has a box behind it to demonstrate how it works on the web

Even when an element has 100% border-radius, the browser treats it as a box as demonstrated by the lighter border

Take the above example: it’s visually a circle—by proxy of border-radius—but it’s still a box, as far as the browser is concerned.

This is really important to remember when you’re working with CSS, but what’s even more important is understanding how these boxes are both sized and how they interact with their surrounding, sibling boxes.

Padding and borders permalink

When we add padding and borders to an element: by default, their values will be added to the computed width and height. This can be confusing—especially when you are first starting out with CSS.

Code language
CSS
.box {
width: 100px;
padding: 10px;
border: 10px solid;
}

A stack of three boxes to represent width, padding and border. Width is set to 100px, while padding and border are set to 10px. There is a measure at the bottom which shows this calculated as 140px

The width, padding and border contributing to a 140px computed value.

What happens here is your box’s computed width is actually calculated as 140px. This is how the box model works, out of the box (pun intended), and it’s expected behaviour. Most of the time though, it’s preferable for this not to be the case, so we add this little snippet of CSS to give us some more sizing predictability:

Code language
CSS
.box {
box-sizing: border-box;
}

This completely transforms the browser’s calculation because what it says is “Take the dimensions that I specified and also account for the padding and border too, instead of adding them to the size”. What you get as a result, is a box that’s 100px wide, instead of 140px wide, just like you specified when you set width to 100px!

The same example as above, but the box is now measured as 100px. This is demonstrated with all of the properties inside one box with a ghost of the old box behind it

The fixed box with a predictable width. The lighter border shows the computed width when you don’t have box-sizing: border-box.

Most folks add the box-sizing rule as a global selector to a reset, or default normalising styles, so to demonstrate a more complete example, this is how our CSS now looks:

Code language
CSS
/* Reset rule */
*,
*::before,
*::after
{
box-sizing: border-box;
}

/* Box component */
.box {
width: 100px;
padding: 10px;
border: 10px solid;
}

What this example does is instead of just targeting the box with box-sizing, it targets every element on the page and any pseudo-elements. This means that everything you add to a page, you can guarantee that your boxes will be the sizes that you think they are. Setting global styles like this is a great way to keep your CSS as simple as possible, because that’s how it’s designed to work.

Wrapping up permalink

You can read more on box sizing over on MDN, where there is some very good documentation.

Setting box-sizing: border-box is such a life saver for front-end developers. This is so much the case that we even have “International box-sizing Awareness Day” on February 1st, every year. Having control of your box sizes is also exceptionally helpful in a responsive design contexts.

The days of CSS before box-sizing arrived were very frustrating days indeed, so hopefully now you know how it works, box-sizing will make your CSS work a lot more fun and much less frustrating.