IE6 absolutely positioned element not inheriting correct parent width

Test case:
http://www.deanclatworthy.com/test.html

What should happen:
As the “Choose your language” text expands, the sub-list should dynamically adjust in size also.

What actually happens:
In IE6 it seems the sub-list incorrectly inherits the width of the #container element.

Browsers it does work in:

  • Latest chrome dev build
  • FF 3.6

I’m not entirely sure about this, but I see this:


#container { width: 960px; margin: 0 auto; }

#language-chooser { clear: both; float: right; border: 1px solid pink; }
#language-chooser ul { list-style: none; border: 1px solid cyan; }
#language-chooser ul li { position: relative; border: 1px solid #ff0000; }
#language-chooser ul ul { position: absolute; top: 31px; right: 0; width: 100%; }

And notice that the rel-po’d li’s don’t have Layout, while the #container does.

So what happens if you state something like
#language-chooser ul li { position: relative; border: 1px solid #ff0000; }
* html #language-chooser ul li {height: 1.2em;}
#language-chooser ul ul { position: absolute; top: 31px; right: 0; width: 100%; }

?

Does it suddenly work or still off?

Hey, thanks for the reply :slight_smile: When I do that it just makes all the li’s (including the “Choose language”) one the same width as #container.

In IE6?

Keep giving layout to boxes then (to see what happens).

#language-chooser { clear: both; float: right; border: 1px solid pink; }

This box has Layout (floated), and it’s a float without a width.

Back in ye olden days, floats were supposed to have widths. The rules got changed, so in CSS2.1 it is legal to have widthless floats, but they can be a source of hair loss.

Can you give someone a width at some point? The children inside can be smaller and if the width’d box doesn’t have any background, you wouldn’t know.

IE6 may have to always have the max width of the width’d box (if I’m right and this isn’t some other IE6 problem). Or, people have been known to size things dynamically for IE6 with Javascript, but that’s a rather unappealing solution.

Yep in IE6. It works fine in the other browsers. I can’t get away with giving any of the list items a fixed width as they are always going to be fluid.

The “choose language” will have a maximum width though.

Somewhere there’s a language who is the longest with that phrase. (or is aakjhfkjhs standing in for some unknown phrase brought in from the server/db?)

let the smarter browsers have no width. Give someone (preferably the float then) a width for IE6 only to give it something to use as a width reference for the dropdown languages.

But first, can we see if anything works by making every single element have Layout? It won’t be pretty, but it’s just for testing. It’s like throwing buckshot at mosquitos but it’s also pretty standard when going up against IE6 bugs (since Haslayout is such a huge source of bugs).

If that doesn’t work and you have to end up giving just IE6 a width on the float, someone in the meantime may answer here who knows more specifically about this bug and might know a better solution.

I know some clients are adamant about how something looks in IE6, but I’m willing and able to let things look a bit different for those folks so long as everything still works for them and doesn’t look too crazy. IE6 users often aren’t checking a site in several other browsers like we are.

I’ve used max-width for language differences on two sites of ours (not an abso-po problem but still, IE6 needed a set width), and we looked at the longest language (in our case it was Spanish because it was a phrase) and then set the width in em (so that text-enlarge still grew).

It’s true that one piece of text will have a maximum width. However we are actively adding more languages on a regular basis so it’s quite inconvenient to have to remember to change the 1 stylesheet every time we do this. I’d rather come up with a CSS solution to remedy the problem. We’re not adamant at work that it must look 100% in IE6 but having this list expand to 100% width instead of what should be between 100-200px is unacceptable as it will actually overlap our logo in the real layout I extracted the test case from :wink:

^yes I agree the 100% is definitely out. However if approx 200px or so is a max (could also try with breathing room) then it’s still some sort of option on the table (preferably with a non-px unit).

I’m looking around the forums to see if someone with the same problem got a better solution. I know IE6 needs to take dimensions from a positioned element (or some ancestor) with Layout, but I don’t know the details when they all are based on some J Random Inline (your anchor).

Thanks for looking into it anyway. I did do a bit of googling beforehand to try and catch up on things. I’m a bit rusty on my CSS as it’s been a few years since I did this as a day job. This is one of the more complex layouts I’m working (thank you designers!) so it’s probably not the best one to get back up to speed with :wink:

As Stomme poes has said, your #container needs to enclose its float child. As you have it, you can’t use {overflow: hidden;}, because it would hide your sub-menu. You can use {display: table;} though.

Howsoever, once you fix the main problem, you can go back to the overflow property. Unless I’ve missed something, there is no reason for this:

 #language-chooser ul ul {
  position: absolute;
  top: 31px;
  right: 0;
  width: 100%;
  }

Instead, do this:

#language-chooser ul ul {}

It is a good practice to leave elements alone sans compelling reason to mess with them. Unless you know what you need to change, you’re just throwing um, stuff at the wall to see what sticks. If you try something and it doesn’t work as expected, remove the changes before moving on. There are exceptions to this, but it’s good to always work from a solid, known base.

cheers,

gary

Hi Gary,

The position absolute stuff is leftover from my code I extracted this test case from. It’s essential to my code as it means that my sublist can overlay any content below it (simulating a select dropdown). IE6 doesn’t support display: table; according to http://reference.sitepoint.com/css/display so I can’t see how that would make any difference to the issue here.

Dean

re: {display: table;}

IE6/7 do not support table display, but the width property triggers hasLayout in those browsers. The display property is used in IE8 and modern browsers to establish a new block formatting context, which for float children is equivalent.

OK, so you’re really going for a drop-down sub-menu. In that case, use the display property on #container. Do the following:

#language-chooser ul ul {
    left: 0;
    position: absolute;
    right: 0;
    top: 31px;
    width: 100%;
    }

cheers,

gary

So wait, Gary, it was the float not being enclosed? But #container had layout so IE6 and 7 should have been (incorrectly) enclosing the float.

I ran briefly into a thread where Paul mentioned a specific problem with IE6, position: absolute and widths when the rel-po’d container either didn’t have Layout OR did but didn’t have a width… that IE6 would not take its width from someone with width: auto on them. But, I looked and looked last night and never found it again (with the same search terms too).

I tried what you suggested Gary, and the menu now correctly aligns with the left position of the parent list (but that’s due to adding left: 0;) I think. But it still incorrectly inherits the parent width of #container. I’ve not updated the example test case as it did not fix the problem.

I need to find that thread from Paul, I remember it had mention specifically about widths and abso-po in IE6… : (

Seriously I type in exactly the same words in the search, I should get the same results : (

Do you mean this one Mallory.

I don’t think it’s possible to get the sub menu to base it’s width on the parent in IE6. You could get all the submenus to be the same width as shown in this fluid dropdown.

What about if I did this with different markup? I’m not bound to a list. I just need to make it so that my “items” are always the same width as their parent and absolutely positioned so they can overlay content below.

They could be relatively positioned and with a high z-index, still sit over the content who comes later.

Stomme, if they were relatively positioned then they would expand the size of the parent container unless you didn’t clear the float but that seems to me like you’re exploiting the float model and wouldn’t be correct (and leave you prone to more bugs).

Stomme, if they were relatively positioned then they would expand the size of the parent container…

Hm, yes they would lose their shrink-wrapping they get as absolute boxes. It seems a bit hackish to then go to display: inline-block, which keeps the shrink-wrapping and allows you to have it relatively positioned so as to be able to state a z-index.