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

HtmlCssInternet Explorer-8

Html Problem Overview


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:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> http://www.w3.org/1999/xhtml" >

<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?

Html Solutions


Solution 1 - Html

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 - Html

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 - Html

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 - Html

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;" />

Solution 5 - Html

As explained by buti-oxa this is a bug with the way IE8 handles replaced elements. If you don't want to add an explicit width to your button then you can change it to an inline-block and center align the contents:

<div style="height: 500px; width: 500px; background-color: Yellow; text-align: center;">
  <input type="submit" style="display: inline-block;" />
</div>

If you want this to work in older versions of Mozilla (including FF2) that don't support inline-block then you can add display: -moz-inline-stack; to the button.

Solution 6 - Html

As far as this being a "bug" with relation to the spec; it isn't. As the author of the post questions, the behaviour for this would be "undefined" since this behaviour in IE only happens on form controls, as per spec:

> CSS 2.1 does not define which > properties apply to form controls and > frames, or how CSS can be used to > style them. User agents may apply CSS > properties to these elements. Authors > are recommended to treat such support > as experimental.

( http://www.w3.org/TR/CSS21/conform.html#conformance )

Cheers!

Solution 7 - Html

One more time: we all hate IE!

<div style="width:100%;background-color:blue;">
    <div style="margin:0 auto;width:300px;background-color:red;">
        Not Working
    </div>
</div>

<div style="width:100%;background-color:green;text-align:center;">
    <div style="margin:0 auto;width:300px;background-color:orange;text-align:left;">
        Working, but dumb that you have to use text-align
    </div>
</div>

Solution 8 - Html

tried all the above, end up doing this

<div style="width:100%; background-color:red; text-align:center;">
		<div style="width:900px; margin:0 auto; background-color:blue;">
			hello
		</div>
	</div>

Solution 9 - Html

Add <!doctype html> at the top of your HTML output.

Solution 10 - Html

> shouldn't the button be 100% width if it's "display: block"

No. That just means it's the only thing in the space vertically (assuming you aren't using another trick to force something else there as well). It doesn't mean it has to fill up the width of that space.

I think your problem in this instance is that the input is not natively a block element. Try nesting it inside another div and set the margin on that. But I don't have an IE8 browser to test this with at the moment, so it's just a guess.

Solution 11 - Html

"margin: 0 auto" only centers an element in IE if the parent element has a "text-align: center".

Solution 12 - Html

  1. Assuming margin: 0 auto then the element should be centered, but the width is left as-is--whatever it is calculated to be, disregarding any margin settings.
  2. If you set the <INPUT> tag to display:block, then it should be centered with margin: 0 auto.

See Visual formatting model details - calculating widths and margins from the CSS 2.1 specs for more details. Relavent bits include:

> In a block formatting context, each > box's left outer edge touches the left > edge of the containing block.

and

> When the total width of the inline > boxes on a line is less than the width > of the line box containing them, their > horizontal distribution within the > line box is determined by the > 'text-align' property.

finally

> If 'width' is set to 'auto', any other > 'auto' values become '0' and 'width' > follows from the resulting equality. > > If both 'margin-left' and > 'margin-right' are 'auto', their used > values are equal. This horizontally > centers the element with respect to > the edges of the containing block.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionstusmithView Question on Stackoverflow
Solution 1 - HtmlPalView Answer on Stackoverflow
Solution 2 - Htmlbuti-oxaView Answer on Stackoverflow
Solution 3 - HtmlWolfrView Answer on Stackoverflow
Solution 4 - HtmlKornelView Answer on Stackoverflow
Solution 5 - HtmlSimon DysonView Answer on Stackoverflow
Solution 6 - HtmlZoffix ZnetView Answer on Stackoverflow
Solution 7 - HtmlzeroasteriskView Answer on Stackoverflow
Solution 8 - HtmlRouslan KarimovView Answer on Stackoverflow
Solution 9 - HtmlMohammad NajiView Answer on Stackoverflow
Solution 10 - HtmlJoel CoehoornView Answer on Stackoverflow
Solution 11 - HtmlChrisView Answer on Stackoverflow
Solution 12 - HtmlJon AdamsView Answer on Stackoverflow