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;
}