[html] 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?

This question is related to html css internet-explorer-8

The answer is


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.


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

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.


  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.


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!


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


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>

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>

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


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.


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


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to internet-explorer-8

HTML embedded PDF iframe IE8 issue with Twitter Bootstrap 3 addEventListener not working in IE8 first-child and last-child with IE8 Box shadow in IE7 and IE8 CSS rounded corners in IE8 How to disable Compatibility View in IE Why an inline "background-image" style doesn't work in Chrome 10 and Internet Explorer 8? IE8 support for CSS Media Query Opacity of div's background without affecting contained element in IE 8?