Daily Tips & Tricks for Web Enthusiasts

Intuitive Box Sizing

CSS is great, but it has some unusual quirks. One of its most annoying oddities has to do with how the width and height of elements are calculated. Take this CSS, for example:

div.example {
    width: 100px;
    height: 100px;
    padding: 10px;
    border: solid 2px;
}

You might expect the div.example element to be 100 pixels wide and 100 pixels high, as those are the values specified for the width and height properties, but you would be wrong. The CSS above will actually result in a div.example that has a width and height of 124 pixels.

Where did the number 124 come from? By default in CSS and element’s dimension are calculated using something called the content box model. That means the area where the content goes, in the middle of an element, are what the width and height properties apply to. So, in this case, our context box is made to be 100 pixels square. Then the padding and border are added on top of that. This results in a width of 124 pixels: 100 pixels of content width, 10 pixels of padding on either side, and 2 pixels of border on either side. 100 + 10 + 10 + 2 + 2 = 124. The height is calculated the same way.

Quirky, isn’t it? That’s not how most people think about this kind of thing. When you write something like width: 100px you expect the thing to be 100 pixels wide, right?

Well, I’ve got good news! You can specify a different box sizing model in CSS that actually does what you would expect. All you need to do is set the box-sizing property to border-box, like this:

div.example {
    box-sizing: border-box;
    width: 100px;
    height: 100px;
    padding: 10px;
    border: solid 2px;
}

Now, instead of the width and height properties applying to the content box in the middle of the element, they instead apply to the outermost border box surrounding the outer edge of the element. This results in a 100 pixel square box, which is much more intuitive.

I don’t know about you, but I vastly prefer the border-box model, which is why I almost always start every new project with the following CSS at the top of the stylesheet, which applies border-box sizing to all elements so I don’t have to think about it again:

* {
    box-sizing: border-box;
}