Home Blog CV Projects Patterns Notes Book Colophon Search

CSS Box Model

13 Aug, 2013

This is the W3C box model, used by pretty much everyone:

+---------------------------+
| Margin                    |
| +-----------------------+ |
| | Border                | |
| | +-------------------+ | |
| | | Padding           | | |
| | | +---------------+ | | |
| | | | Content       | | | |
| | | |               | | | |
| | | |<--- Width --->| | | |
| | | |               | | | |
| | | +---------------+ | | |
| | +-------------------+ | |
| +-----------------------+ |
+---------------------------+

This is the Internet Explorer box model, used by Internet Explorer:

+---------------------------+
| Margin                    |
| +-----------------------+ |
| | Border                | |
| | +-------------------+ | |
| | | Padding           | | |
| | | +---------------+ | | |
| | | | Content       | | | |
| | | +---------------+ | | |
| | +-------------------+ | |
| |                       | |
| |<------ Width -------->| |
| |                       | |
| +-----------------------+ |
+---------------------------+

Basically, Internet Explorer treats width as the width of the content, the width of the padding and the width of the border, whereas every other browser treats the width as just the width of the content.

Consider this styling for this content:

<div class="box">
  Content
</div>
.box {
    padding: 10px;
    border: 2px solid #000;
    width: 200px;
}

In IE, the div would actually be 200px wide, whereas in every other browser it would be 224px wide, because the border and padding wouldn't be part of the width calculation.

If I'm being honest the IE way of looking at things make a lot of sense to me, and in browsers that support CSS3 it is handy that you can make things work that way using this:

box-sizing: border-box;

To be safe though there is a very simple rule:

Never apply a width to an element that has a border or a padding.

In practice this means that the example above has to change to:

<div class="box">
  <div class="box__content">
    Content
  </div>
</div>
.box {
    width: 200px;
}
.box__content {
    padding: 10px;
    border: 2px solid #000;
}

Now all browsers behave like Internet Explorer without needing CSS3 or any hacks. The only downside is an extra <div> in the underlying markup, but really, compared to the hassle of having to deal with two box models otherwise, this is a price worth paying.

Of course, if you deliberately want to make your site look very broken in old IE browsers so that users migrate, not applying the above fix is a really good way of doing it!

Also, in practice it is worth extending the rule to never use a margin with a width either. This allows you to use percentage widths easily for fluid layouts.

The final rule becomes:

Always apply widths to outer elements, and border, margin or padding to an inner element so that the outer width is calculated predictably

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.