April 9th, 2008 - by Paul OB

Sometimes the simplest things can turn out to be more complicated than you ever imagined. This can sometimes be the case with CSS and cross-browser support. It’s no wonder that beginners to CSS often throw their hands up and revert back to using tables because some bug or other has thrown them off course.

As an example I thought I’d document a few problems that crop up time and time again with absolute positioned elements in our favorite browser – yes, IE6, I’m talking about you again!

Removed From The Flow

Absolute elements are removed from the flow and have no affect on surrounding content. Conversely surrounding content should not be able to affect absolute elements either. That’s not quite true as a positioned element will create a stacking context for further positioned elements but that’s as far as any effect will go. (We often set position:relative on a parent so that the absolutely positioned child can be placed in respect of that parent and not the viewport.)

In effect the absolute element should not care what else goes on around it and is oblivious to anything except its own start position. IE, however, has a few peculiar issues with this in the simplest of layouts and we will document a few of the most common and thought-provoking problems you will encounter on a day to day basis.

The following examples are a little contrived in order to show the effects at the simplest level and could be done by other methods but that’s not the point of the Lose Weight Exercise.

The Disappearing Margin Trick

The following example creates an absolute element at the top of the page which is 100px high. The following element is static but has a margin top of 100px to move it below the absolute element by 10px (remembering that absolute elements are removed from the flow so that the margin is taken from the top of the container and not the absolute element).

  1. #outer{
  2.     width:300px;
  3.     margin:auto;
  4.     border:1px solid #000;
  5.     position:relative;
  6. }
  7. .abs{
  8.     position:absolute;
  9.     top:0;
  10.     left:0;
  11.     width:300px;
  12.     height:100px;
  13.     background:red;
  14. }
  15. .follow{
  16.     margin:110px 0 0 0;
  17.     width:300px;
  18.     height:100px;
  19.     background:yellow;
  20. }
  1. <div id="outer">
  2.     <div class="abs">Absolute element</div>
  3.     <div class="follow">Following block</div>
  4. </div>

If you run this code in Firefox you will see something like the screenshot in Figure 1.

Figure 1
abfig01.gif

The code couldn’t be simpler as it’s basically two lines of code but let’s see what IE makes of it.

Figure 2
abfig02.gif

As you can see the yellow block which follows the absolute element has completely disappeared in both IE6 and IE7.

Where has it gone?

Although I said the yellow block has disappeared that’s not quite true. If we reduce the width of the absolute element we can see the yellow block skulking underneath the red block.

[CSS]
.abs{
position:absolute;
top:0;
left:0;
width:200px;/* width reduced*/
height:100px;
background:red;
}
[/CSS]

With the absolute element’s width reduced, the yellow block can be seen at the edge shown in Figure 3.

Figure 3
abfig03.gif

So what can we deduce from this?

It would seem that the top margin on static content is ignored in IE when it follows immediately after an absolutely placed element in the HTML.

For my next trick….

We know the issue is not a “haslayout” issue because the element already has a “layout” due to the width we gave it. Let’s try floating the following content instead and see if that fixes the problem for us.

  1. .follow{
  2.     margin:110px 0 0 0;
  3.     width:300px;
  4.     height:100px;
  5.     background:yellow;
  6.     float:left;/* float added*/
  7. }

All we have done is to add float:left to the static content and the result is shown in Figure 4.

Figure 4
abfig04.gif

Well things are looking much better in IE7!

IE6 is also showing the yellow block in the correct position but unfortunately IE6 has now hidden the red absolutely positioned block!

Obviously floating fixes IE7 but leaves IE6 still broken so it’s not a solution we can use.

What else can we try?

Let’s first remove the float we just added so that we are back to the original code and try something else. The following solution is one that I have tried and tested and probably posted 2 or 3 times a week in the forums. We won’t change the CSS at all but instead address the HTML. If we move the absolutely placed element to the end of the current stacking context then all these problems disappear.

[HTML]

Absolute element

[/HTML]

All we have done is to move the div that has a class of “abs” to the end of the current stacking context (i.e. to the end of #outer). The result of that simple change can be seen in Figure 5 below.

Figure 5
abfig05.gif

Both IE7 and IE6 now display the elements correctly. It’s a pain that the HTML has to be changed but I have found that this is the only reliable way to squash this rather annoying bug.

And there’s more….

The strangeness doesn’t stop there I’m afraid. If we use the new revised HTML but change our yellow block to be floated we observe another strange behavior in IE6 and under.
[CSS]
.follow{
margin:110px 0 0 0;
width:300px;
height:100px;
background:yellow;
float:left;
}
[/CSS]

The result of adding float makes the absolutely placed red block disappear altogether as shown in Figure 6 below.

Figure 6
abfig06.gif

We fixed our original problem by changing the order of the HTML which made everything work fine but now that we’ve added a float to the element following the absolute element we find that the absolute element has disappeared again. Damn!

Obviously we can’t change the HTML around again because we already know that it won’t work so what could be a solution this time?

This leads to a solution that I haven’t seen documented before (except by me) and the logic of the solution is nonsense which is why it probably hasn’t been noted before. In order to make the absolute element re-appear we add clear:both to the absolute element!

Of course this makes no sense because absolute elements are removed from the flow and therefore should not be affected by floats. Clear floats in our current example would seem to have no bearing in any shape or form. However, believe it or not by simply adding clear:both to the absolute element it miraculously re-appears.

The HTML is still as follows:
[HTML]

Absolute element

[/HTML]

  1. .abs{
  2.     position:absolute;
  3.     top:0;
  4.     left:0;
  5.     width:300px;
  6.     height:100px;
  7.     background:red;
  8.     clear:both
  9. }

Figure 7 shows that finally all elements are present and correct in IE6.

Figure 7
abfig07.gif

As I said at the start of the article the examples are a little contrived but that was in order to show the full effect of these strange bugs in the simplest of situations. Now that you know what they are and how they occur you will be able to fix them easily when it happens to you. The things to look out for are disappearing absolute elements or disappearing and misplaced content next to absolute elements or when floats follow absolute elements in the HTML. The full-proof solution is to move the HTML for the absolute element to the end of the current stacking context and then to add clear:both to it.

IE makes CSS so much fun — if things were to just work the first time, where would be the fun in that?

51 Responses to “CSS – An Absolute Mess”

1 Golgotha

Fantastic article Paul! And good timing too as I have an article draft started on why I really dislike answering the question, “Are you good at JavaScript and CSS?” in job interviews. I think I am good at both, but it’s usually cross-browser stuff like this that makes me cringe on the question…

2 Paul OB

Glad you liked it Mark :)

Look forward to reading your article.

3 obiddle

Last night I decided I was going to solve this problem and not work around it. I found a another solution using {padding: 1px 0;} in my bottom div.

http://www.owenbiddle.com/2008/04/unwanted-spacing-between-your-divs-in.html

4 Paul OB

@obiddle: Thanks for your comments :)

The issue you mention is a different collapsing margin problem and is very different from the example posted in the article.

Collapsing margins is exactly how things are supposed to work according to the specs and you just need to make sure that you have something solid like padding or borders between your adjacent margins. This will stop the collapse from extending through adjacent margins.

I have written extensively about this and similar topics and you can read up on the exact details here (if you are interested :) or have the time).
http://reference.sitepoint.com/css/collapsingmargins
http://www.search-this.com/category/css/page/4/
http://www.search-this.com/2007/09/05/lets-be-clear-about-this/
http://www.search-this.com/2007/08/01/the-positive-side-of-negative-margins/

This search-this article though has nothing to do with the normal collapsing margin problem although a margin does collapse its not the usual issue (if you get my meaning).

Padding or borders will have no effect in any of the demos on this page although I can see why you may have mistaken it for the usual collapsing margin issue. :)

5 Daniel

Excellent clear explanation. Added to my set of tips and tricks – Thanks!

6 id

I wonder when all browsers will pick industry standards for CSS presentation.

7 Paul OB

@id: Hopefully IE8 will be better as the betas look promising. Most other modern browsers are pretty good and consistent

8 Golgotha

Hopefully IE8 will be better as the betas look promising. Most other modern browsers are pretty good and consistent

That’s great, but my wife and most of IBM are still using IE6…

9 Dr Richard

Great article. Two tips – (1) look at http://www.positioniseverything.net and (2) do you development on Firefox and get the Firebug plugin. These two have saved me hours of CSS frustration!

10 Ivan

Great article, Paul, love the final sentence :))

11 John

If we move the absolutely placed element to the end of the current stacking context then all these problems disappear.

In real world usage of this kind of example, you’d probably find that people would have the absolutely positioned element last in the source anyway (otherwise why use absolute positioning and margin the other content away?).

So it’s probably not a bug that many would encounter, but good to know what the solution is.

12 obiddle

thanks for the response Paul OB. I put you on my daily reads and linked to the proper post you directed me to.

13 Andy

Please think about the title of your articles.

I nearly missed this jem simply because the article doesn’t accurately convey the content.

14 Matthew Pennell

Perfect timing – I encountered this problem last night, and gave up in the end, so your article couldn’t have been any more serendipitous. Simple fixes FTW!

15 Tony Crockford

What I normally do in an instance like this is to add top padding to the container to make space for the absolutely positioned element.

avoids all cross browser concerns and makes more sense to me.

see it here: http://www.boldfishclient.co.uk/test/paulob/

16 Paul OB

Hi John,

Yes as I mentioned in the article I contrived the code to make the example work in as few lines of code as possible and usually you would not do it this way. :)

However, I do encounter this problem on almost a daily basis in the forums because the situation can also arise when the absolute element is in the middle of the current context which is the way most people are doing it. The absolute element needs to go right at the end which may even be after the footer.

17 Paul OB

Hi Tony,

Thanks for your comments :)

Yes you could apply padding top to the main container to make room for the absolute elements and it will work ok but the point of the article was to show situations where things won’t work. :)

However, even in your example if you add float:left to the element with a class of .follow then the absolute element disappears again in IE6. (Of course the following element doesn’t need to be floated but there will be some situations where this may occur.)

Your method also throws up another interesting bug in that if you do as I said above and float .follow and then add clear:both to the absolutely positioned element in your layout, you will find that the absolute element re-appears but now there’s be a gap under the yellow box that seems to be caused by your padding method! (is there no end to IE’s madness)

There are many minor solutions and other strange behaviours that can occur in various situations depending on width/float etc and I believe the method I posted avoids these in most cases. Although I don’t doubt there will be other fixes also :)

18 Paul OB

@Tony, Sorry I forgot to mention that the .abs element also needs to be moved to the end of the stacking context as well when you try out the changes I mentioned to your example.

19 Tony Crockford

Well, I can see what you’re trying to say, but I can’t think of any real life situations where I’d want to combine an absolutely positioned element, followed by a floated one – that’s a nightmare waiting to happen!

Pragmatically I avoid absolute positioning whenever I can, for the reasons you describe. But, judicious use of floated relatively positioned containers (with top padding) and absolutely positioned elements can get round a lot of real life challenges.

;)

20 ToddZ

Nice article, but titling it “CSS – An Absolute Mess” sounds like an inappropriate slam at CSS.

It should be called “IE6 – An Absolute Mess”

Or “IE6 – an abominable plague that should be cleansed from existence” …or some such…

21 Golgotha

Ha ha, Ok maybe the title could have been improved, but the keyword is “Absolute”. The title plays on the Absolute element factor :)

22 Paul OB

Hi Tony,

Yes the examples area little contrived and I agree that in most cases using the padding is a good solution :)

However (you knew this was coming didn’t you), using your example of padding I can come up with an example that may be more true to life and if you look at the following in ie6 (or ie7) you can see it is completely broken.

http://www.pmob.co.uk/search-this/absolute/example8.htm

It is used in the situation that most people would try to use it and placing a header to the top of the page from beyond the content. The content is 2 columns and therefore has to be floated. This is a situation that would normally occur and isn’t as contrived as the other examples.

However using the padding method doesn’t allow for any fixes to work in this situation. To get everything to work correctly you need to use the margin method as shown in the following example.

http://www.pmob.co.uk/search-this/absolute/example9.htm

I guess we could go on all day finding different things that don’t work in IE lol :)

23 Mr IE

i wonder when all browsers will pick standards for CSS presentation and realize IE is used by 80% of the people in the world, and thats the standard you should be using, guess the majority doesn’t matter. I plan to start a movement and filling our CSS’s with Firefox and other hacks… just to let the few people who think they are right see out web pages.

j/k

24 web

I didn’t read through all the comments but I would have tried adding a padding-top to the outer element.

Margins are sometimes kinda funky in regards to when they collapse and when they don’t.

25 Paul OB

Hi Web,

It would have helped if you had read the last few posts lol :)

The padding issue has been covered in detail (see tony’s posts above) and has just as many bugs and indeed insurmountable bugs as shown by example 8 in post 22.

The behaviour isn’t just about margins as elements will disappear on other occasions also but the margin example was the shortest 2 line code example I could make :)

Thanks for the comments anyway :)

26 Colin

This probably would have solved something that was bugging the hell out of me last week.

My coworker and I always joke that there are a few CSS rules that might as well be “ie: work;” They are “position: relative” and “zoom: 1″

I think I’ll be adding “clear: both” to that suite.

27 Joey

Great article on fixing some of the mess IE6 brings to the table.

On another note, I have to agree with ToddZ, this really should be called “Internet Explorer 6 – An Absolute Mess”.

28 Franca Richard

Really nice articles, you know I am learning css and crazy for it these days!

29 Franca Richard

CSS is ART! suddenly wanna shout here!

30 John

I encountered an interesting variation of this bug today. I had two images that I had positioned absolutely after some floated content. I initially had the position: absolute on the images themselves but IE6 was stretching and distorting one of the images even though the only dimensions set for it were in the HTML. Wrapping the image in a <p> and positioning that instead solved the problem. :?

31 Links of Interest - CSS-Tricks

[…] actual title of the article is “CSS – An Absolute Mess”, but I retitled it here to something less linkbaity and more accurate. Nonetheless, a valid […]

32 James

Nice article Paul.

Yet another IE bug to note for the future!

33 Craig

Great article, as a freelance website designer I absolutely hate it when I have a customer that is still in ie6. I do anything in my power to get them to upgrade vs. adding a style sheet for ie6. And soon we will be faced with ie8. Everyone should be made to upgrade to the latest version of the browser that they are using. But thanks for the cross browser css references.

34 John

Everyone should be made to upgrade to the latest version of the browser that they are using.

I don’t agree with that. People shouldn’t be forced to do anything. It’s up to them what browser they use and it’s up to you as a designer how much effort you go into making your designs work in certain browsers.

You can choose to not cater for IE6’s quirks and people can choose to use IE6 and not use your site if it doesn’t work that well for them.

35 Oleg

Someone might have already mentioned that, but I think the better solution here might be having padding-top:110px on #outer div, so then you don’t have to alter your html ;)

36 Tsalagi

Blah blah blah. The most popular browser(IE) developers doesn’t care about it’s end users. Yet everyone continues to use it. It’s a practice of social idiocy.

37 Paul OB

@Oleg: Yes using padding has already been covered in depth and dismissed by me in post #25 because of insurmountable bugs in certain situations. The solutions I gave still stand and are more reliable.

Also as already mentioned the point was to show the bug in action and not to “not show the bug in action”. :)

38 oleg

Hey, Paul could u please give me the link to that post. I am genuinely interested in reading it ;)

39 Paul OB

@Oleg: It’s in the comments above you in post#22 and #25.:)

Here is the link to the padding example in a more real life situation which shows that it is badly broken in IE. This was in answer to Tony’s posts about using padding as you have also suggested.

http://www.pmob.co.uk/search-this/absolute/example8.htm

As you can see it is badly broken in IE and can’t in fact be fixed unless you change to my methods mentioned in the article.

I hope you find it useful and thanks for the comments anyway :)

40 Stuart Steel

Hey,

great article. This is a bug I’ve come across a couple of times and not really understood – I’ve certainly never seen it documented like this.

My usual strategy for mystery IE6 bugs is:

1/. Try position: relative;
2/. Try adding a border (surprising how often this works)
NOW
3/. Try clear: both

Thanks

[…] are some problems with positioning absolutely, this article by paul’OB describes them quite […]

42 Rehan Anis

Dear All
I have used that clear:both in my css to solve the position of a relative div which overlaps the other floating divs.
This has solved the problem for IE6 and FF2, but IE7 now overlaps the div which it wasn’t before adding the clear:both command.

How to solve it?

[…] are some problems with positioning absolutely, this article by paul’OB describes them quite […]

44 Andreas

In my ie6.css, referenced through a conditional comment, I was able to solve this by adding these rules:

#absoluteblock
{
clear:both;
float:left;
position:relative;
}

Don’t ask me why this works in IE. position:relative?? It boggles my mind.

You may have to move #absoluteblock and any following floats up by the height of #absoluteblock. In my case, I had to add a negative margin of 100px to #absoluteblock and my following floated block.

[…] CSS – An Absolute Mess […]

46 Jeff Broderick

Great! Worked like a charm!

47 bigraffa

Fantastico!!! Grazie mille!

48 stinkypizza

Thanks a lot! Been looking for this solution all over the web. Great to have found it here! Good job! :-)

49 Tom Ho

Great article, i just had this problem with one of my clients’ website.

50 Z-index problem in IE 7 - SitePoint Forums

[…] or perhaps position:relative is needed if overflow is used (in IE7). Absolute elements have a number of bugs in IE6 and 7 and sometimes the only fix is to move the element into another position. Usually this […]

51 Web Design Code, Tutorials, & Tools « Eric's Logic

[…] CSS – An Absolute Mess […]

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading