Using "margin: 0 auto;" in Internet Explorer 8

I'm in the process of doing some advance IE8 testing, and it seems that the old technique of using margin: 0 auto; doesn't work in all cases in IE8.

The following piece of HTML gives a centered button in FF3, Opera, Safari, Chrome, IE7, and IE8 compat, but NOT in IE8 standard:

<div style="height: 500px; width: 500px; background-color: Yellow;">
    <input type="submit" style="display: block; margin: 0 auto;" />
</div>

(As a work-around I can add an explicit width to the button).

So the question is: which browsers are correct? Or is this one of those cases where the behaviour is undefined?

(My thinking is that all the browsers are incorrect - shouldn't the button be 100% width if it's "display: block"?)

UPDATE: I'm being a dunce. Since input isn't a block-level element, I should have just contained it within a div with "text-align: center". Having said that, for curiosity's sake, I'd still like to know whether the button should or shouldn't be centered in the example above.

FOR THE BOUNTY: I know I'm doing odd things in the example, and as I point out in the update, I should have just aligned it center. For the bounty, I'd like references to the specs that answer:

  1. If I set "display: block", should the button be width 100%? Or is this undefined?

  2. Since the display is block, should "margin: 0 auto;" center the button, or not, or undefined?


Solution 1:

Adding <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> solves the issue

Solution 2:

It is a bug in IE8.

Starting with your second question: “margin: 0 auto” centers a block, but only when width of the block is set to be less that width of parent. Usually, they get to be the same. That is why text in the example below is not centered.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <b style="display: block; margin: 0 auto; ">text</b>
</div>

Once the display style of the b element is set to block, its width defaults to the parents width. CSS spec 10.3.3 Block-level, non-replaced elements in normal flow describes how: “If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.” The equality mentioned there is

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

So, normally all autos result in a block width being equal to the width of containing block.

However, this calculation should not be applied to INPUT, which is a replaced element. Replaced elements are covered by 10.3.4 Block-level, replaced elements in normal flow. Text there says: “The used value of 'width' is determined as for inline replaced elements.” The relevant part of 10.3.2 Inline, replaced elements is: “if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'”.

I guess that the scenario CSS cares about is IMG element. Stackoverflow logo in this example will be centered by all browsers.

<div style="height: 100px; width: 500px; background-color: Yellow;">    
    <img style="display: block; margin: 0 auto; " border="0" src="http://stackoverflow.com/content/img/so/logo.png" alt="">
</div>

INPUT element should behave the same way.

Solution 3:

Yes, you can read the spec a hundred times, and combine different bits and pieces until you have an interpretation that feels right – but that's exactly what the browser vendors did and that's why we're in the situation we are today.

In essence, when you apply a width of 100% to an element it should extend to 100% of it's parent's width, if that parent is a block element. You can't center it anymore with margin: 0 auto; then since it already takes up 100% of the available width.

To center anything with margin: 0 auto; you need to define an explicit width. To center an inline element, you can use text-align: center; on the parent element, although this could have unwanted side-effects if the parent has other children.

Solution 4:

Form controls are replaced elements in CSS.

10.3.4 Block-level, replaced elements in normal flow

The used value of 'width' is determined as for inline replaced elements. Then the rules for non-replaced block-level elements are applied to determine the margins.

So the form control should not be stretched to 100% width.

However, it should be centered. It looks like an ordinary bug in IE8. It centers the element if you set specific width:

<input type="submit" style="display: block; width:100px; margin: 0 auto;" />