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

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.
  • Site-relative links such as <a href="node/123"> will work correctly.

More information about formatting options