I have a code snippet element that I want to stretch to 100% of its parent. Easy peasy. Here's the code:
<div class="container">
<div class="box">
Code snippet
</div>
</div>
.container {
width: 400px;
border: 5px solid black;
margin: 10px;
}
.box {
background-color: #407AA4;
border: 3px solid red;
line-height: 100px;
color: #fff;
text-align: center;
width: 100%;
padding: 0 10px;
}
Wait! Why does it overflow like that? When we inspect the element we can see that its width is 426px meanwhile its parent is 400px. What is going on?
This, my friend, is a CSS box-sizing problem. But before we fix it we need to understand why it happens. In order to do that first we need to make friends with CSS Box Model.
Box model
CSS Box Model is a way the browser represents each and every HTML element in the DOM Tree.
It consists of 4 layers, where the previous one is surrounded with the following one, just like the onion:
- content (blue) - changed by:
font-size,line-height,height, etc. - padding (green) - changed by:
padding,padding-left,padding-top, etc. - border (orange) - changed by:
border-width - margin (brown) - changed by:
margin,margin-left,margin-top, etc.
How can I see the Box Model of a given element?
Fortunately, every major browser has a way to visually represent the model in their DevTools, which we can open in a couple of steps:
- Hit
Ctrl + Shift + Cwhen in browser and click on the element of choice. - Inside opened DevTools in the
Elementstab clickComputedtab. - Bam. That's all.
- You can repeat from step 1 to pick a new element or just click the tag in the
Elementstab DOM Tree.
The box-sizing problem
Now that we know the basics we can say hi to the CSS box-sizing property. It can have one of 2 values:
- content-box (default)
- border-box
content-box
When we tell the browser that we want an element to have 100% width, like in our case, the browser:
- Gets the width of the parent, in our case 400px.
- Sets the elements content width to 400px.
- Adds 20px of padding (to left and right). Now width is 420px.
- Adds 6px of border (to left and right). Now width is 426px.
- Puts the element inside the parent.
Our calculation matches the width measured empirically.
How can we fix it?
border-box
The solution is to set the box-sizing: border-box to the .box element.
The browser now:
- Gets the width of the parent, in our case 400px.
- Sets the elements content width to 400px.
- Subtracts 20px of padding (to left and right). Now width is 380px.
- Subtracts 6px of border (to left and right). Now width is 374px.
- Puts the element inside the parent.
The steps remained almost the same, but in steps 3 and 4 instead of adding padding and border the browser now subtracts them.
If we take a look at the elements Box Model now we can see that the calculations checkout.
How to avoid this kind of problems in the future?
The very first thing I do at the beginning of every project is I add this piece of CSS code:
* {
box-sizing: border-box;
}
This selector applies border-box value to every element in the DOM Tree, so that we don't have to worry this specific case anymore.
But be careful when you do this in your existing codebase, because all the layouts had been adjusted to the content-box calculations and there is a high chance that something might break.
Conclusion
In this article we've made friends with CSS Box Model and box-sizing property. We now know how the browser performs calculations regarding content-box and border-box properties. We've also learned what to do at the start of every project.
The full example can be explored here.
In the next articles we will get to know the lonely wanderer called quirk modes and flirt with rendering layers concept.
See you around.







Top comments (0)