IE와 W3C의 박스 차이에 의한 CSS 코딩 방식

2007. 9. 11. 10:35Programming/CSS

IE와 W3C에서 사용하는 BOX의 크기는 다르게 설정되어있어서 사이즈가 다르게 나오는 것들이 많이 있다.

이를 해결하기 위한 방안이 아래 설명되어 있다.

이하는 원문의 내용을 발췌한 내용..

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

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.


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.

1 ··· 3 4 5 6 7 8