Internet Explorer and the CSS box model

One of the differences between Internet Explorer and standards compliant Web browsers that cause a lot of trouble for CSS beginners is the CSS box model. Since the box model is what browsers use to calculate an element’s total width and height, it is quite understandable that different browsers producing different results can be both confusing and frustrating.

How the CSS box model works has been explained by others many times already. Nonetheless I still see questions related to the CSS box model on forums and mailing lists, and frequently encounter sites that expect browsers to use Internet Explorer’s non-standard way of calculating box dimensions. That is why I have written this article, which to a large extent is a translation of an article I wrote for Swedish magazine CAP&Design earlier this year.

If you already know how the different box models work and how to handle Internet Explorer, there is nothing new for you here. If you get different box dimensions in IE and other browsers without knowing why, keep reading.

The CSS box model diagram

Here is a simple diagram showing how the dimensions of an element are related in CSS:

The Internet Explorer CSS box model includes padding and borders in the value assigned to the width property.

For the purposes of this article, all browsers handle the margin property the same way when calculating an element’s total width, so I’ll be concentrating on the padding and border properties.

The W3C Box model

First a look at the the W3C box model, which is used by all standards compliant browsers and by Internet Explorer 6 and later if the circumstances are right. In the W3C CSS box model a block level element’s total width is calculated using the following formula:

total width = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right

The same concept applies to height, but for the sake of simplicity I will only talk about width from now on.

The IE Box model

The IE Box model is similar except for one important difference: paddings and borders are not included in the calculation:

total width = margin-left + width + margin-right

This means that if the element also has horizontal padding and/or borders, the actual content area will shrink to make room for them.

IE versions

Versions 5.5 and earlier of Internet Explorer for Windows always use the IE Box model. What many do not seem to be aware of is that IE 6 and later use the W3C box model when in standards compliant mode. This is a good thing since it means that problems will only occur in IE/Win 5.5 and older, provided that you use a DOCTYPE that makes IE use standards compliant mode.

Attacking the problem

By making sure that IE 6 is in standards compliant mode, you only have to care about this whole thing if you still are concerned about your sites looking the same in IE 5.*/Win as in more recent browsers. If that includes you there are several ways of attacking the problem, listed here in my order of preference:

  1. Avoid situations that cause problems
  2. Insert extra markup
  3. Use conditional comments
  4. Use CSS hacks

Since the problems caused by the Box model differences are often only cosmetic, my personal preference is to simply not bother with IE 5.*/Win. Sometimes that isn’t acceptable and I have to use one of the methods I’ll describe here.

1. Avoid situations that cause problems

This is how I prefer to solve the problem. I simply avoid specifying both width and padding or border for the same element. This ensures that all browsers will use the same total width, no matter which box model they use.

Let me use an example to illustrate. The HTML used to mark up a list of news articles could look like this (simplified):

  1. <div id="news">
  2. <h2>News</h2>
  3. <ul>
  4. <li>
  5. <h3>News article 1</h3>
  6. <p>Lorem ipsum dolor sit amet</p>
  7. </li>
  8. <li>
  9. <h3>News article 2</h3>
  10. <p>Lorem ipsum dolor sit amet</p>
  11. </li>
  12. </ul>
  13. </div>

To make the list 250 pixels wide with a one pixel border and 10 pixels of padding, you could use the following CSS:

  1. #news {
  2. padding:10px;
  3. border:1px solid;
  4. width:228px;
  5. }

In standards compliant browsers, the total width will be 250 pixels (1px left border + 10px left padding + width + 10px right padding + 1px right border). In IE 5.5 and earlier, the total width will be 228 pixels since it doesn’t add paddings and borders.

So how can you avoid this? Let’s assume that the news list is in another container, for instance a sidebar:

  1. <div id="sidebar">
  2. <div id="news">
  3. ...
  4. </div>
  5. </div>

If that is the case you can set the width on that container instead:

  1. #sidebar {width:250px}
  2. #news {
  3. padding:10px;
  4. border:1px solid;
  5. }

Since #news is a block level element it will automatically fill the entire width of its parent element, which in this case is #sidebar.

2. Insert extra markup

If you can’t use method 1, another method is to insert extra markup. Using the same example as previously, assume that #news is not supposed to expand to the full width of #sidebar. Specifying a width for #news to prevent that is a the scenario you want to avoid. A workaround is to change the markup to this:

  1. <div id="news">
  2. <div>
  3. <h2>News</h2>
  4. <ul>
  5. ...
  6. </ul>
  7. </div>
  8. </div>

and use the following CSS:

  1. #news {width:250px}
  2. #news div {
  3. padding:10px;
  4. border:1px solid;
  5. }

The outer element controls the width, and the inner element contains the border and padding.

It’s up to you to decide whether it is a reasonable compromise to add extra markup like this. It is obviously better if you can avoid doing so, but an extra div element doesn’t cause any other problems than increased file size and slightly reduced markup maintainability. It does not affect accessibility or how the document is presented with CSS off. Besides, having an extra element is necessary to create certain designs, so you may already have the markup you need.

3. Use conditional comments

If there is no suitable element that can be used to control the width and you can’t or won’t add extra markup, IE 5.*/Win needs to get a different value for width.

In my opinion, the safest way of doing that is to use conditional comments, which are comments whose content is only visible to IE/Win. In this case only IE below version 6 are supposed to get the contents:

  1. <!--[if lt IE 6]>
  2. <style type="text/css">
  3. #news {width:250px}
  4. </style>
  5. <![endif]-->

If you choose to use this method I recommend moving all IE 5.*/Win specific CSS to a separate file and load it like this:

  1. <!--[if lt IE 6]>
  2. <link rel="stylesheet" type="text/css" href="/css/ie5.css">
  3. <![endif]-->

This is a safe way of ensuring that only the browsers that need the modified CSS see those rules.

4. Use CSS hacks

Finally you can also use a CSS hack to supply modified values to IE 5.*/Win. I recommend avoiding CSS hacks as much as possible. Just like the name implies, these are hacks, and hacks that are based on undocumented errors in different browsers’ CSS parsing. Since many people still use CSS hacks I’m mentioning it anyway. I highly recommend that you consider other options before using them unless you know exactly what you are doing.

The simplest CSS hack for working around box model problems is The simplified box model hack, SBMH. Provided that the HTML is the same as in the first example, the CSS would look like this:

  1. #news {
  2. padding:10px;
  3. border:1px solid;
  4. width:250px;
  5. w\idth:228px;
  6. }

All browsers see and understand width:250px. IE 5.*/Win does not understand the next line, w\idth:228px, which all standards compliant browsers do. The result is that width is set to 250px in IE 5.*/Win and 228px standards compliant browsers, giving the list the same total width in all browsers.

Conclusion

As I have shown here it is possible to avoid or work around the problems caused by the different CSS box models. Which method you use will depend on the circumstances.

I should also mention that some time in the distant future, the CSS 3 `box-sizing` property will let you choose which CSS box model you want browsers to use. The W3C box model is called `content-box` and the Internet Explorer box model is called `border-box`. Being able to control this in all browsers is a good thing since each model has its pros and cons. However, browser support is currently too limited for this property to be of any practical use.

Hopefully none of this will be necessary in a couple of years. IE 7 was released in October 2006, and for every day fewer and fewer use the older versions of IE. It is already acceptable for some sites to hide all CSS from IE/5.* or to simply not care about the rendering differences.

I’ll leave it to you to decide when you can start hiding CSS from IE 5.*/Win.

Posted on December 21, 2006 in CSS

Comments

  1. Excellent article Roger. My preferred method of dealing is avoiding situations that will cause me grief. Perhaps this is related to that, but I would like to add one to your “Attacking the problem” list:

    Let go and allow things to be as is. In other words allow for these differences in the design. Obviously this won’t apply to all situations — like a pixel-perfect layout — but it is another method of “Attacking the problem.” Not attacking it at all by allowing a less rigid styling that will look good no matter what box model is used.

  2. Out of interest, why do you prefer adding extra mark-up to conditional comments?

    I always insert an IE 5-specific stylesheet via conditional comments anyway to deal with IE 5’s different model for font sizes in tables. I stick any necessary box model fixes in there.

    I prefer coding to the standards first, and keeping any browser-specific workarounds in obviously browser-specific areas, i.e. conditional comments. I just wish other browsers implemented them so that we could fix old Firefox bugs too.

  3. Really nice article! But perhaps it should be noted that the css hack isn’t supported by older versions of Opera, and therefore perhaps isn’t a good solution at all if you don’t extend it with some extra css? Just learned from the article you refered to :)

  4. Good article, Roger!

    As Mike I also prefer to just avoid getting into trouble with the box model-bug since I’m not getting paid for trying to hack IE’s bugs. :)

    On the other hand, when a problem is unavoidable I usually use conditional comments instead of adding extra markup. The conditional comment just lets the IE users download the extra CSS file, leaving the other users unbothered.

  5. Unfortunately I’ve had to work without standards compliant mode for the last couple of months, working on a Notes site; due to a bug with Notes you can’t properly declare the DOCTYPE - although someone on the Port 80 (AWIA) forum showed me a hack for that which I’m going to try implement in a Notes site redev next year - very much looking forward to it! IE FTL.

  6. December 21, 2006 by Brett Mitchell

    In response to number 2 by pauldwaite;

    I think it’s because when you use conditional comments and want to change the width or border or padding, you have to calculate and change the value twice. With extra markup, you change it just once.

  7. I’m able to handle the width/height issues with the !important syntax.

    http://www.dustindiaz.com/min-height-fast-hack

  8. So what if like Nathanael you have to work with a system like Notes/Domino that doesn’t allow you to change the DOCTYPE to a standards compliant DOCTYPE? Even if you could change the DOCTYPE, you might not want to use a standards compliant DOCTYPE since Domino produces non-strict HTML. For instance it doesn’t end list items and sometimes puts in a the beginning of paragraph but doesn’t end it.

    In this case all versions of IE use the Microsoft box model, but what to other browsers like Firefox, Safari, Camino or Opera do?

  9. I mostly go with Mike Cherim’s solution. As long as there is no breakage, I don’t worry about a bit of distortion.

    But, I will admit to not caring a whole lot unless the client is paying a premium for IE5.x support.

    Conditional comments are an issue with me. I organize my stylesheets by context, which implies that hacks should be adjacent to the original selectors. The CCs separate hacks from the defaults, making debugging or maintenance more complex than it should be. IE7 is still a virtual unknown, so I don’t know just how I’ll be dealing with its shortcomings; conditional comments are not a preferred solution.

    cheers,

    gary

  10. How about using the “margin:10px” in the div#news rather than “padding:10px”. That might solve the problem in situations where padding isnt really required (like when there is no background to be thought of, etc.)

  11. That was good explanation of IE’s box model, Well as long as we have browsers that just won’t observe the discipline, we’ll have to use either of your tricks. I personally would still prefer the extra markup. As that is not something extra ordinary like the “w\idth” thing, and still solves the purpose.

  12. fran

    I’m able to handle the width/height issues with the !important syntax.

    A hack is still a hack. If someone says “hack,” inelegant is not far behind. To quote the article you link to:

    Assuming IE6 will not fix the correct implementation for the !important declaration and assuming that if IE7 does, they’ll also implement min-height correctly since at the pace they’re going they’re fixing CSS like mad crazy cows. Is that too many assumptions? But wouldn’t you agree?

    Yes, I think it assumes too much. No, I wouldn’t agree. I respect Dustin a lot. But using CSS hacks, even if they are never fixed, when conditional comments are readily available seems like misplaced effort. Granted it was 2005 and CSS hacks (and “discovering” them) were all the rage when the article was written. Now, though, conditional comments make CSS hacks obsolete.

    Conditional comments are A Hack Apart, though. Ideally, something like #1 could be used to better ends. But if you need IE to read something different than other browsers, conditional comments are the way to go because they are either supported or ignored, rather than misinterpreted.

  13. My preferred method is to avoid situations that cause problems, and keep IE6 in quirks mode whenever possible. I’ve never found IE6’ ‘standard mode’ to be very ‘standard’, and the box model problem is not a real problem, IMO.

    So, by triggering ‘standard mode’ in ‘standard compliant browsers’ (including IE7 in most cases), and handling IE6 and older IE/win versions as ‘quirks mode’ browsers, the old ‘* html’ hack is available for fine-tuning of the ‘IE box model’ or whatever else older IE/win may need.

    @Tanny O’Haley

    In ‘quirks mode’ Opera will fall back to the old ‘IE box model’. Firefox, and probably the other browsers you mention too, will fall back to the old ‘NN4 box model’, which I haven’t studied but I think it is closer to the ‘W3C box model’. Anyway, by following #1: ‘avoiding situations that cause problems’, there aren’t all that many differences to worry about.

    Also: leaving out optional end-tags for list-items and paragraphs is perfectly valid HTML, and should not cause any problems. That means that you may add a ‘standard-triggering HTML doctype’ just for the sake of triggering browsers, and get a near perfect result across browser-land. Browsers use full ‘error-recovery’ for HTML anyway, regardless of mode.

  14. December 22, 2006 by Anders Tornblad

    @divya:

    Margin and padding are not supposed to be handled the same way by browsers. Paddings are always additive, while top and bottom margins are not.

    Example

  15. A method I use to avoid the situation without additional markup is to only apply padding to the element’s children (e.g., header and paragraph elements). Do others do this?

  16. December 22, 2006 by Brian Crescimanno

    I’m confused as to why this is being posted now. Using a proper doctype, IE6.0 and newer uses the correct w3c box model. No need for hacks or workarounds—just use a doctype to put the browser into “standards” mode.

  17. @Anders Tornblad:

    Margins are handled a bit more complex than your example shows. You’re into collapsing margins, which means you can get the result you want - not just the one you describe.

    @Brian Crescimanno:

    I think that’s why Roger wrote:

    If you already know how the different box models work and how to handle Internet Explorer, there is nothing new for you here. If you get different box dimensions in IE and other browsers without knowing why, keep reading.

    Sure, we know the ‘different box models’ and ‘standard compliant mode’ and all that stuff more or less ‘inside-out’, but there are plenty around who do not - or simply can’t control ‘browser modes’. Some things are worth repeating.

  18. December 22, 2006 by Anders Tornblad

    @Georg:

    That is very true! I just wanted to make a point that paddings and margins are not completely interchangeable.

  19. I stopped supporting IE5 about half year ago. It’s just not worth it. Now IE5 receives unstyled content and site remains fully functional. So even if someone is stucked to IE5 it’s not big deal.

  20. Thanks!

    The markup on Blogger makes more sense now. Not, you know, a whole lot more, but a little.

    -M

  21. Does anyone know of an elegant way to prevent web pages in IE5.x from being styled? Would @media {} work?

  22. bart - I’m doing it by content negotiation on server but it’s not solution when you want to have static files. The only other way I know would be the use of @media {} and IE conditionals but I’m not sure is it great solution (especially @media {} part)

  23. @Bart:

    Elegant - no! Working - yes.

    Stylesheets imported via…
    @import “style.css”/**/;
    …will not show up in IE5.x on win and Mac.

    Tantek’s High Pass Filter…
    @import “null?"{“; @import “styles.css”; @import “null?"}”;
    …will also block IE5.x/win.

    @media wrappers will only block IE4, NS4 and IE/Mac.

  24. It seems that there are at least as many ways to fool IE as there are developers out there. Let me join the crowd with my own one:

    1- design for the w3c box model and keep IE in standards mode

    2- add an IE < 7 stylesheet to help the old clunky behave with crosshover.htc, PNG alpha filters and other stuff I don’t want in my main CSS file

    3- add this to the very end of the IE-only sheet:

    @media tty { i{content:”";/” “/}}@m; @import ‘ie55.css’; /”;} }/ */

    @media tty { i{content:”";/” “/}}; @import ‘ie50.css’; {;}/”;} }/ */

  25. @ Anders Tornblad:

    I didnt mean to replace padding everywhere, but use it in areas where it would be better suited like what Georg outlined.

    Thanks for the clarification though!

  26. Like the majority of people hear, I just do not use padding anymore. It has caused me great grief in the past with it working fine in Firefox and then looking out of whack in IE.

    I also agree that you should not use hacks. I have only ever used one hack and that would be for the min-width problem that IE does not allow.

  27. A very good article that explained the problem at hand which has had me stumped before.

    Like the majority of people hear, my solution is that I just do not use padding anymore. It has caused me great grief in the past with it working fine in Firefox and then looking out of whack in IE.

    I also agree that you should not use hacks. I have only ever used one hack and that would be for the min-width problem that IE does not allow.

  28. Your ie box model diagram is priceless. thank you.

    e- Ateavablog

  29. January 4, 2007 by Max Bode

    Nice article! I just don’t get why everyone is so upset with the IE box model?! Ignoring the fact that only the IE supports it, in my opinion it’s a lot better than the W3C box model.

    If you are working with percentages you should know what I mean. Just add one border in px and your whole concept is no longer working using the W3C model. In my opinion it is a lot easier working with the IE box model.

    Well I probably haven’t got the expert knowledge to see the W3C box models advantages…

  30. There are many of us who can’t grasp the box model situation because it always seems, to me anyway, that boxes are bigger, not smaller, in IE.

    A floated layout that works like a charm in real browsers blows up in IE until I make the margins/paddings SMALLER.

    If the “larger” size works in FF, why would it blow up in IE if the box is smaller?

    I can understand the concept as shown in the diagram, it just doesn’t seem like that’s the case in reality.

    (It bothers me because, no, I am NOT really really stupid! But it is making a fool out of me)

  31. January 19, 2007 by Stephen Marx

    @31, Dave Brimlow:

    It sounds like you may be falling prey to IE doubling the margins of your floated elements. You can read more about the problem here: http://www.positioniseverything.net/explorer/doubled-margin.html

  32. Options 2 and 3 are obviously the things you should avoid at all costs - better stick to CSS maneuvers. At least you keep the advantage to change only one file, in the best case.

    This screams for more coverage, right.

  33. Thanks, Stephen Marx. Can it really be as simple as: {display: inline;} ??!!

    Lovely.

    Funny, I am constantly sending people in forums to “PIE”, I finally took my own advice … even though it came from someone else!

  34. @medyk

    Yup, very very true, man. Dealing with work arounds for old stuff costs a lot of nerves, always drives the webmaster crazy and it is mostly not worth it. Speaking from own experience… :|

  35. March 14, 2007 by richard

    Hi

    Can I get your point of view on the bug described at: http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug

    isn’t their graphic as compared to yours confusing? it seems to show IE rendering widths correctly, yet has a footnote to say - as opposed to the W3C spec.

  36. March 14, 2007 by Roger Johansson (Author comment)

    richard: The Wikipedia graphic looks correct. I noticed that this article is listed among the references :-).

  37. March 15, 2007 by richard

    Yes it’s nice they reference you - things make sense here!

    Sorry to carry on with this, but are you saying about their diagram - yes this is how IE renders from IE6 onwards, or yes they show the IE5 bug correctly?

    If the latter then why is their diagram showing IE5 to be wider than the W3C spec?

    As you explain here (as they do), IE5 constrains to the content width adding padding and borders within, while standards compliant browsers add on the padding and borders thus making the element wider. So as I see it the W3C and IE widths on their diagram are the wrong way round.

  38. March 15, 2007 by richard

    ah, okay. Having s l o w l y read it, now I understand!

    their diagram is not a physical representation as here. it only shows that IE5 contains borders and padding within the element width.

    I still maintain that the diagram confuses though as it makes it look like IE5 renders wider i.e. correctly.

    I can sleep restfully now.

  39. Just wanted to add — I encountered my first case of IE doubling margins on floated elements and was able to fix it utilizing the Tan hack (http://tinyurl.com/9yld6). I just re-specified the margin value in the css hack that was in the original rule and it killed the doubling and preserved my floats.

  40. Thanks for this clear understanding of the box models. It helps with an IE 6 problem we have been having.

  41. By experience: Use “display: block” and quite often all is okay.

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.