If there’s ever one really important thing to remember when writing CSS: it’s that every element is a box. Regardless of how an element looks visually, it’s still a box.
Take the above example: it’s visually a circle because it has border-radius
applied to it, but it’s still a box, as far as the browser is concerned.
This is really important to remember when you’re working with CSS, but what’s even more important to remember is understanding how these boxes are both sized and how they interact with their surrounding, sibling boxes.
Padding, borders and the content boxpermalink
The default box-sizing
value for all elements is content-box
. This means that when we add padding
and/or border
to an element, those values will be combined with the desired/content-driven width
and height
of the element.
This is because the width
is applied to the content box part of the box box model. This can be confusing — especially when you are first starting out with CSS.
- Code language
- css
.box { width: 100px; padding: 10px; border: 10px solid; }
What happens here is your box’s computed width is actually calculated as 140px
. This is because each side of the border box is 10px
(20px
combined), and each side of the padding box is 10px
(20px
combined). The width of the box only accounts for these inline sizes.
This is how the box model works out of the box (pun intended), and it’s often unexpected behaviour for beginners because y’know, if you set a width
or height
, you expect your element to honour that. It’s completely understandable how this confuses people!
Most of the time though, it’s preferable for this default box model behaviour not to be the case. To get more predictability, add this little snippet of CSS to your element’s CSS:
- Code language
- css
.box { box-sizing: border-box; }
This snippet completely transforms the browser’s calculation of an element’s size. To convert this CSS into plain English, you’re saying: “Take the dimensions that I specified and also account for the padding and border too, instead of adding them to the desired size”.
What you get as a result is a box that’s 100px
wide, instead of 140px
wide, just like you specified when you set width
to 100px!
The most effective way of showing you this is with a demo. When you toggle the “box sizing” switch to ON, box-sizing: border-box
is applied to the box element, making the resulting size the same as the desired size. When it’s switched OFF, the default browser behaviour takes over.
See the Pen A quick demo showing the impact of box sizing on a box element by piccalilli (@piccalilli) on CodePen.
The element has 10px
of padding
and a 10px
border, which means 40px
is added to the width because the element has padding and border either side. The demo box has a minimum size of 250px
to make the text easier to read.
Globalising box sizing rulespermalink
A lot folks add the box-sizing
rule as a global selector to a reset — or default normalising styles — so to demonstrate a more complete example, this is how our CSS now looks:
- Code language
- css
/* Reset rule */ *, *::before, *::after { box-sizing: border-box; } /* Box component */ .box { width: 100px; padding: 10px; border: 10px solid; }
What this reset rule does is instead of just targeting the .box
element with box-sizing
, it targets every element on the page and any of their pseudo-elements.
This means that every time you add and element to a page, you can guarantee it will be the size that you think it is with little to no surprises. Of course, in a responsive world, setting specific sizes can be problematic, but even then, you know padding
and border
are not going to make your elements bigger than you thought they’d be.
Wrapping uppermalink
I hope this quick run-through of the box model and box sizing has unlocked the concept in your brain. Knowing the fundamentals like this will make you a better CSS developer, I promise. Here’s some links:
- Box Model - web.dev
- The box model - MDN
- The CSS Box Model - Margin, Borders & Padding explained - Kevin Powell
- Happy international box sizing awareness day