IE inherited margin bug: form elements and hasLayout

Internet Explorer on Windows has a wide variety of rendering bugs. Many of these bugs can be worked around by giving affected elements the IE-specific "hasLayout" property and an extensive analysis of how and when this works is available. This article describes the opposite situation: an IE rendering bug that is triggered by elements having layout for which the workaround is to remove the hasLayout property.

The bug is that certain form input elements whose containing box has layout inherit the sum of the margins of all of their containing boxes. Unlike the the well known IE doubled float-margin bug, this one does not involve floats. There is a workaround but, so far, no magic-bullet CSS-only solution.

The Problem

Consider this sample code:

<form action="ignore">
<div style="width: 50%; margin-left: 5em; background-color: tan;">
  INPUT tag, type=text:<br />
  <input type="text" /><br />
  INPUT tag, type=checkbox:<br />
  <input type="checkbox" />
</div>
</form>

What should be displayed is a tan box, 50% of its parent's width wide, whose left edge is offset 5em from the left edge of its parent. Inside the box should be four lines of content, two text and two form elements, all flush against the left edge of the box.

Here is how it actually displays:

INPUT tag, type=text:

INPUT tag, type=checkbox:

If you are using IE/Win 6 or 7 (I have not yet tested it on other versions), notice that the left edge of the text input field (the second line) is pushed to the left. It inherited the left margin of its parent box because the parent has a width property, giving it hasLayout. Another example:

<form action="ignore">
<div style="margin: 2em;">
<div style="width: 50%; margin-left: 5em; background-color: tan;">
  INPUT tag, type=text:<br />
  <input type="text" /><br />
  INPUT tag, type=checkbox:<br />
  <input type="checkbox" />
</div>
</div>
</form>
INPUT tag, type=text:

INPUT tag, type=checkbox:

Here we see that the affected input element actually inherits the the sum of the left margins of all of its ancestors. Interestingly, it does not inherit the top or bottom margins.

The bug seems to occur for all INPUT types except checkbox, radio, and image as well as TEXTAREA elements but not for SELECT elements.

Workarounds

The problem only seems to occur when the direct parent of the INPUT element has hasLayout and any ancestor has margins. This leads to several possible workarounds:

  • Set a negative margin on the INPUT element equal to the sum of all of its parents' margins. This is fine for static sites but if you are using a CMS it is probably not possible without scripting. Keep in mind that only some INPUT element types are affected; assigning negative margins to checkbox, radio, or image inputs will break your layout.
  • Remove the margins from all ancestor elements. This is not particularly realistic.
  • Remove the hasLayout-granting style from the containing DIV. Since you presumably put that style there for a reason, this is also not particularly realistic.
  • Put inline text, a LABEL, or possibly any inline element at all immediately before the INPUT element. The fact that this solves the problem is probably why more people have not noticed it. Example:
    <div style="width: 50%; margin-left: 5em; background-color: tan;">
      INPUT tag, type=text, preceeded by inline text:<br />
      Text: <input type="text" />
    </div>
    INPUT tag, type=text, preceeded by inline text:
    Text:
  • Wrap the INPUT element in an unstyled SPAN, LABEL, or, in fact, any container element without a hasLayout-granting style. Example:
    <div style="width: 50%; margin-left: 5em; background-color: tan;">
      INPUT tag, type=text, wrapped in an unstyled SPAN:<br />
      <span><input type="text" /></span>
    </div>
    INPUT tag, type=text, wrapped in an unstyled SPAN:

If anyone knows a more general magic bullet for this, or other situations under which the bug occurs, please let me know.

Comments

I came across this exact

I came across this exact same bug and I'm very greatful. I discovered on my own that including any text before the input element would cause the element to no longer inherit the property, but what I didn't know was that it only happens when the "direct parent" has margin properties. I simply implemented an unstyled <div> (or <span>) around the element. I'd go as far as calling this the magic bullet! This won't affect rendering in other browsers and certainly solves this annoying problem with IE. Thanks again.

Thank you for this article!

Thank you for this article! I've been tearing my hair out over this for the past couple of days. I had figured out that it was inheriting the margin, but didn't know how to fix it.

I also documented this

I also documented this margin inheritance bug back in late October -- for a few minutes I thought the IE7 team had forgotten to fix the floated element/margin doubling bug, since I was working with blockified floated labels without a background color or border. I'm a little bitter about the position is everything article, but granted, you did a more accurate writeup & found more workarounds. Nice catch with the text-on-the-same-line-as-the-form-element fix. I updated my post to reflect your findings. Nice work.

Thanks for this. I was

Thanks for this. I was about to give up, then I found your site. The span method works very well and doesn't affect other browsers.

Thanks for the article. Like

Thanks for the article. Like many others I wasted hours trying to figure out this problem (thanks for nothing Microsoft).

Why can’t they (all browsers) just provide a uniform viewport and let their feature set (tabs, extensions, etc.) drive the popularity of their browser?!

Do they really beleive someone will chose to use IE exclusively because some site xyz uses pretty proprietary Microsoft Gradient Filters and IE calculates their box model differently? </vent>

I've never seen this bug.

I've never seen this bug.

Thank you so much for the

Thank you so much for the span wrap!! I was going out of my mind with input alignment!! Damn IE!!
And it was only happening on IE7!!!

I've been struggling for a

I've been struggling for a while with a hidden field between two 0px margin divs pushing them apart. This showed me what was happening. Setting their margin explicitly to 0px fixed it. Though not completely the same problem, I'm a happy man after reading your article.

I've found that when it

I've found that when it comes to forms, IE has issues rending styles that aren't in a paragraph tag. Try using <p> to separate your form elements instead of <br/>, and then you won't have to use any other workarounds. If you don't want the extra line breaks, simply make a class for your p tag that sets margin to 0 and only use it in your forms.

Great article man, helped me

Great article man, helped me out alot ..
Thanks again

Another fix: I had the same

Another fix: I had the same problem, another quick fix is to add padding to the containing element rather than a margin, this of course is only possible when you are using the margin/padding for positional purposes where there is no visual impact. If you have borders or background colour on your containing element it will affect your design.

Thanks for the great

Thanks for the great article. As someonme starting out this type of info saves me plenty of time trying to figure out these bugs. I guess Microsoft does not have enough cash to properly design things!

Thanks so much for this!

Thanks so much for this! This is exactly what I was looking for.

Thank you for this article!

Thank you for this article! I've been tearing my hair out over this for the past couple of days.

Yet another workaround

Yet another workaround –
If the wrapper is floated, display inline will do the job:
div.wrapper { float: left; display: inline; }

Enjoy, Simon

I've been struggling for a

I've been struggling for a while with a hidden field between two 0px margin divs pushing them apart. This showed me what was happening. Setting their margin explicitly to 0px fixed it. Though not completely the same problem, I'm a happy man after reading your article

I guess i should thank you

I guess i should thank you as well as this bug was a source of unhappiness in the past couple of days for me....
Great article, indeed:)

This finally fixed the

This finally fixed the stupid bug for me. Apparently it happens for <h[x]> elements as well. I had to wrap the element in a span, then trigger layout on the element itself.

I thought your great article

I thought your great article would solve my problem. Unfortunately, none of the fixes works for me. So I am re-thinking wheather it is actually the inherited margin bug that I struggle with. Nevertheless, I give it a try and post my problem here. If it's a too long or off-topic comment, please feel free to remove it.

Simplified, I have the below markup and styles. DOCTYPE and structure are fix. Everything behaves like it should in Firefox. The forward button is positioned via width and margin-left in the upper right corner of the content div (with the given padding). With pixel values (width: 150px; margin-left: 408px; (405px for IE6's 3px bug)) even IE shows the button like it should.

With em's it's quite different. Now IE oddly adds some more margin-left to the button, but it isn't as much as the margin-left of the parent content div. It's more like the left+right padding of the content div or something to that extent.
As a result, IE 6 pushes the content div to the right more than the wrapping main div allows. The content div therefore jumps below the floating navigation div.

IE7 doesn't ruin the overall layout, but puts the forward button as much to the right as IE6 does.

As of now, I've only come across one acceptable solution: when I declare the left margin in per cent, everything seems ok.
However, I'd like to know what is wrong with my em's. I hope I haven't overlooked anything simple.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>IE's inherited margins bug</title>
<style type="text/css">

body {
    font: 75% Verdana, Arial, Helvetica, sans-serif;
    line-height: 1.5;
    background: #CCC;
}

input, select, textarea {
    text-align: left;
    font: .916em Verdana, Arial, Helvetica, sans-serif;
    border: 1px solid #000;
    padding: 2px;
}

#main {
    width: 66.667em;
    border: 1px solid blue;
    margin: 1em;
}

#navigation {
    padding: 0 1.667em;
    float: left;
    margin-bottom: 1em;
}

#navigation input {
    color: #FFF;
    background: green;
    border: 0;
    cursor: pointer;
    width: 14.5em;
    height: 2em;
    padding-left: 2em;
}

#content {
    background: #FFF;
    margin: 0 0 0 16.667em;
    padding: 1.667em;
    width: 46.5em;
    border: 1px solid #000; 
}

.buttonSubmitJump {
    background: red;
    width: 13.64em;
    text-align: right;
    margin: 0 0 1em 37.1em;
    padding: .182em 20px .45em .45em;
    height: 2em;
    cursor: pointer;
}
</style>
</head>
<body>
<div id="main">
<div id="navigation">
    <form name="Home" action="" method="POST">
        <input type="submit" name="Home" value="Home" title="Home">
    </form>
</div>
<div id="content">
    <form action="" method="POST">
        <input type="submit" name="submit" value="forward" class="buttonSubmitJump" title="forward">
    </form>
</div>
</div>
</body>
</html>

Instead of wrapping the

Instead of wrapping the INPUT in a span, it would be better to use a div with a "display:inline" style.

very good methods, it work

very good methods, it work fine, I plan to use this on my customer project, very thanks.

Thanks so much for this fix!

Thanks so much for this fix! What a lifesaver!

I am having similar problems

I am having similar problems with my website, but instead of horizontal I get vertical alignment problems with my "

seems to be fixed in ie8b1

seems to be fixed in ie8b1

If you add style="margin:0;"

If you add style="margin:0;" to the form element, that also works. As long as your sub-elements have their own alignments, all should be fine.

Thank you for the solution.

Thank you for the solution. I was beginning to think this is one of those IE bugs you have to live with.

Thanks for your hint. See

Thanks for your hint. See another related bug with the IE6 and floating margins:
Float in Float IE6 margin wrong inherted div width Bug

Works like a charme. Thanks

Works like a charme. Thanks a lot...

I got it working using CMS

I got it working using CMS Box's workaround. Thanks for telling me :-)

The unstyled span tag works

The unstyled span tag works perfectly. I can't believe IE still has bugs like this! Thanks for your help.

Thanks! I could not work out

Thanks! I could not work out what was causing this problem as the elements were not floated. Also as 3px happened to be the amount added margin-left I thought that it could have been releated to the float bug somehow.

Wrapping the input's within a div:

<div>
    <input... />
    <input... />
</div>

..worked like a charm!

Thank you so much.

Thanks, Fixed my problem

Thanks, Fixed my problem straight away!

Thanks so much from me too.

Thanks so much from me too. This was the last hurdle I had to overcome in a time-critical project. The most elegant solution in my case was the one suggested by Simon (CMS BOX), as I already had a floated container - giving it display: inline was all I needed. But the explanation in the actual article was most helpful as well.

Thanks a lot for the

Thanks a lot for the workaround examples! Just had the problem - and now I have a solution.

Great fix, quick and easy!

Great fix, quick and easy! Thanks.

I cannot tell how fantastic

I cannot tell how fantastic this fix is for me! I'm now searching for days to solve that shi... IE behaviour. Really a great description! Many, many thanks bjaspan!

Another fix, which won't

Another fix, which won't alter your markup:

For all parent elements using margin-left (in my case, to make room for labels which had position: absolute and a fixed width), substitute those "margin-left: x" with "position: relative; left: x; margin-right: -x;" -- has the same effect, unless you're using a fixed width, in which case, don't use margin-right but instead change "width: y;" to "width: y-x;".

This fix was necessary in my case since I couldn't change the HTML (I'm trying to make hack-free semantic HTML markup the company standard) but had free reign over the CSS.

You are a hero and made my

You are a hero and made my day :D

It works fantastic. Thank you

It works fantastic. Thank you very much for this short solution.

Genius! THX a lot!!!

Genius! THX a lot!!!

My name is Kurt. I'm

My name is Kurt. I'm interested in similar subjects. I want to say thanks to the author.
I'm owner of Kredyty & konta osobiste.
Have a nice day

The pull-down menu in the

The pull-down menu in the tools area of ie8 is grayed out and that’s why I can’t get to it. I’ll try nvda and see if I can turn it back on that way. Running WinXP Corperate.

IE8 has a giant BUG in it's

IE8 has a giant BUG in it's implimentation of SSL. And rather than displaying a warning when there's a domain name mismatch (Helloooo M$, welcome to the fact that 80% of sites are on SHARED servers!) along the lines of "Hey, there could be a problem, you should be sure this site is who they claim to be", IE8 responds with 2 choices:

With pixel wide (width:

With pixel wide (width: 130px; margin-left: 864px; (861px for IE6's 3px bug)) even IE show the button like it should.

Thanks for solution.

Thanks for solution.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <i> <h1> <h2> <h3> <blockquote>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options