Not so long ago, in the dark times when browsers did not have native developer tools, and Internet Explorer 6 was dominating the web landscape inflicting pain and sufferings to all of the Front End developers in the world, the fundamental property of CSS that is the box model, the formula that dictates how widths and heights sizes should develop for an element on the page, Micro$oft decided that it had to develop inward in the elements.
So by setting height and/or width for example to 100px, borders to 10px and padding to 20px, the computed size on the page will stay 100px, but for the model defined in the CSS specs the computed size should become 130px.
The CSS specs expect that borders and paddings will develop outside of the element content box, adding to the width and height either computed or defined. Since that one or the other behavior can be preferred on different contexts, and since the damage was done already, it was decided that modern browsers would follow the originally intended outward model, but leaving decisional power to the developer gifting them with the box-sizing CSS property.
This CSS3 property has been supported since early versions of all major modern browsers, including Internet Explorer 8, with just a couple of known exceptions on stack overflow and caniuse.
Tables and percentage paddings are a bad mix
One case where the old model comes handy, in which dimensions are added inside from the element’s borders (border-box), is for example when we have one or more containers aligned in a row using dynamic widths, so that when windows size changes the elements can stretch while keeping proportions between its containers, and the contents within each container would adapt accordingly, this comes easy with a <table> element with cells in a row.
In this example the content of the cell on the left has 100% width so that it can fully expand within its container and a small padding to leave some space should it reach the adjacent right cell, but inspecting the element the padding-right: 1.5% is not computed inward to the element but outside of it effectively ignoring the box-sizing directive resulting in a width of 101.5%.
Intrigued by this behavior I made a small snippet that tests the box-sizing in three contexts:
- container and content <div> with padding in percentage unit
- container <table> and content <div> with padding in percentage unit
- container <table> and content <div> with padding in fixed unit
Executed in a modern browser, all three examples will display the same computed width, while on IE8 in the second example the content is kicked out of its container, which means that it’s best to avoid using percentage paddings when the container is a table and the content should be driven by border-box.