hasLayout.net

Share |

Negative Margin Bug

Affected Versions

This bug affects: IE7, IE6

Symptoms

Part of the element that is outside the container disappears when negative margins are used

Date of the Tutorial

Fri Jul 17 02:53:43 2009

Description

Update: I found that solutions presented here do not fix a special setup with negative margin-right and height set to percentage values or right set to any value (even auto). I've posted demo showing both cases where my solutions do not fix the problem. I'll post an update if I ever find a solution

The bug is easy to notice. You set some margin on the element inside an element with "layout" to a negative value so it would escape a bit from its container and viola: IE cuts off the part of the element that is outside the container. Let's take look at the demo.

Demo

I am cut off
Text
More text
HTML Code:
<div id="container">
    <div id="inner">
        I am cut off<br>
        Text<br>
        More text<br>
    </div>
</div>
CSS Code:
#container {
    margin: 2em auto .5em;
    padding: 2em 0;
    width: 80%; /* width gives layout */
}
    #inner {
        margin: -4em 2em 0; /* negative margin is used */
    }

In this demo width: 80% gives the container layout which is one of the trigger requirements. When this demo is viewed in Internet Explorer the top part of #inner, the one that goes out of the #container, will be cut off.

Solutions

Below are solutions for the above bug ordered by the solution type.

Solution (Clean Solution) - with Side Effects

Date of the Solution

Fri Jul 17 03:06:49 2009

Fixed Versions

5.5 and 7

Description

The cleanest way to fix this bug is to remove layout from the container.

The methods to make an element loose layout vary. The idea is to not use any properties that give an element layout. Keep in mind that it is not always possible; for example, when properties that give layout are crucial to the page style or an element has layout by default.

Let's see how we can fix our demo using this method.

First of all, since one of the triggers is container having layout, this is exactly where we should start looking - <div id="container">. A quick scan of the CSS code for the demo reveals that #container has width property, which in turn gives it layout. We need to loose it. How? Since the set width is in percent units (80%), let's try using margins instead. And since we already have auto value for our left and right margins, we will need to make them both equal (10% each).

Here is it, fixed demo:

I am cut off
Text
More text
HTML Code:
<div id="container">
    <div id="inner">
        I am cut off<br>
        Text<br>
        More text<br>
    </div>
</div>
CSS Code:
#container {
    padding: 2em 0;
    margin: 2em 10% .5em; /* 10% left and right margins, no width */
}
    #inner {
        margin: -4em 2em 0; /* negative margin is used */
    }

Fixed version looks the same as original demo, however the bug does not appear anymore.

Side Effects

Removing layout from the container causes peek-a-boo bug to appear in IE versions below 7. If you are supporting such versions consider using "layout solution" for this bug.

Solution (Layout Solution)

Date of the Solution

Fri Jul 17 03:11:38 2009

Fixed Versions

all of the affected

Description

This solution uses hasLayout on the element with negative margins itself as well as position: relative as an extra kick that is needed to stabilize the fix.

Here is a fixed version of our demo using this method.

I am cut off
Text
More text
HTML Code:
<div id="container">
    <div id="inner">
        I am cut off<br>
        Text<br>
        More text<br>
    </div>
</div>
CSS Code:
#container {
    margin: 2em auto .5em;
    padding: 2em 0;
    width: 80%; /* width gives layout */
}
    #inner {
        margin: -4em 2em 0; /* negative margin is used */
    }
Conditional Comments:
    <!--[if lte IE 7]>
        <style type="text/css">
            #inner {
                zoom: 1;
                position: relative;
            }
        </style>
    <![endif]-->

Everything is pretty straight forward. Giving #inner layout makes the part that is outside #container appear. And position: relative is what helps prevent the disappearing background bug.

Comments

Create new comment
  • John Lardinois

    Fri Feb 3 08:36:19 2012

    I believe there are two ways to fix this - use z-index with position absolute, or simply put overflow visible.

  • Lukas

    Mon Aug 29 05:20:35 2011

    If the second solution does not work, check if the container is set to position: static. Mine was position relative and it didn't work. When I set it to static everything turned out ok.

  • Bharat

    Thu Aug 4 10:43:30 2011

    Thank you for solution

  • yoe

    Thu May 26 12:01:45 2011

    thanks for the solution for me it worked better to set a height on the inner cont.

  • mandrade

    Thu Dec 23 12:37:11 2010

    Thanks for the tips but I found this problem happened in ie8 as well when the inner container was a table. I wanted to position an h1 outside of the table using negative margins but it didn't work!! I ended up having to use relative positioning instead because your fix wasn't working :(

  • Nate

    Wed Nov 3 16:55:49 2010

    Thanks so much! ... now that IE6 is more or less dead, IE7 has graduated to the bane of my existence.

  • N/A

    Wed Oct 13 08:41:29 2010

    thanks for solution

  • cnc137

    Mon Aug 2 18:19:45 2010

    Thank you for the tip! I am glad I searched for the answer on Google instead of pulling my hair out. :)

    I found your article by searching for the following phrase if you were wondering:

    "negative margin internet explorer 6"

  • Mark

    Thu Jul 1 11:27:19 2010

    Thanks so much for this.

    My problem was actually in Safari where I had a div with buttons at the bottom and a negative margin-bottom. This was followed by a second div.
    Visually it looked fine but because the second div technically overlapped the buttons the links didn't work.

    The position:relative has sorted it.

  • Pawel

    Mon Jun 21 13:18:49 2010

    Thank you very much for those solutions. You really help me guys ;)

  • Lex

    Thu May 20 06:17:58 2010

    Thanks nice fix :D. Finally found the solution because of you :D.

  • roberto

    Wed May 5 12:35:41 2010

    great fix.. i've cracking my noggin trying to fix that issue.. i honestly hate ie6 xD

  • Bek

    Mon Apr 5 04:29:02 2010

    Just to add a simple solution to this. Simply adding
    position:relative;
    to the affected div will solve the problem. :)

  • Ben

    Tue Mar 16 23:36:57 2010

    OMG, this was a lifesaver. Thanks!

  • mores

    Mon Feb 22 12:39:13 2010

    Thanks for the zoom/relative thing. Helped me mighty.
    Gosh darn it I hate IE. Why is it always this browser that adds an extra 10% of work to my projects?

  • Paul Duffy

    Tue Jan 19 15:38:34 2010

    Nice one. This can cause an issue with nested divs as well. The negative margin was on the parent div but was causing the child div's background and borders to appear at the extent of its margins (so no nesting further divs for faking borders either).

  • Matt Smith

    Tue Dec 29 11:22:08 2009

    Many thanks! I was using a negative margin to allow for spacing on an image bullet. Wasn't working in IE6, but with your "Layout" solution, it now does!

  • Mark

    Tue Dec 22 13:40:42 2009

    thanks for the helpful tip. ie7 drives me bonkers. I used the position: relative trick in an alternative ie7 stylesheet. worked like a charm. :-) thanks!

If you found materials on this site useful, please consider donating a few bucks to the author. Thank you.

Alternatively, purchase my book:

Support Wikipedia