box-sizing: border-box explained

A drawing of a cartoon man pointing upwards

Heads up! This post was written in 2014, so it may contain information that is no longer accurate. I keep posts like this around for historical purposes and to prevent link rot, so please keep this in mind as you're reading.

— Cory

It's been over two years since Paul Irish famously posted the box-sizing trick that would bring us back to the days of early Internet Explorer.

The good ol' days #

You might remember how Internet Explorer 6 (quirks mode) and below did that whole box model thing wrong. If not, here's a refresher.

A comparison of the W3C box model to that of old IE

You might even remember what a pain it was to develop with. We're not talking about the days of conditional comments, we're talking about the days of horrible CSS hacks littering stylesheets. You know, like this one:

div {
    width: 100px;
div {
    \width: 140px;
    w\idth: 100px;

This hack tricked older versions of Internet Explorer in such a way that the div would be the same width in IE and W3C-compliant browsers. (I don't think I need to go into detail about why this was a bad idea.)

The funny thing is, we've more or less come full circle to the very model we were fighting against. You see, the border-box trick actually brings us back to the way old IE worked. And it's glorious. There's even a special day for it.

How it works #

The border-box trick effectively changes the way dimensions are measured for every element so it includes borders and padding. Here's the code, for reference:

html {
  box-sizing: border-box;
*, *:before, *:after {
  box-sizing: inherit;

Think of it as a box model reset that will make you enjoy writing CSS. It's a tried and tested method that works all the way back to IE8, and is used in popular frameworks such as Bootstrap. There are no performance issues—it's like a little piece of magic on your webpage.

But some of my plugins look funny now #

I've noticed this a few times before. If you're using a third party plugin whose styles rely on the content-box model, things might look a bit strange. To fix this, you can create an override class or apply the following styles directly to a parent element of the plugin:

.content-box * {
  box-sizing: content-box;

This resets the container and everything inside to the default box-sizing model, so third-party plugins will render correctly.

Pick your box model #

The two most common values for box-sizing are border-box and content-box, but another has been introduced more recently. As it's name implies, padding-box measures the element's width, height, and padding but not its border. (Support for the new property isn't great yet, so avoid using it for anything serious.)

To better understand each property, here's a diagram for reference.

A diagram showing the three values for box-sizing: content-box, border-box, and padding-box

Oh, and before you ask: no, there's no margin-box.