Aleksandar • Vacić

iOS bits and pieces

Those things that refuse to obey

While developing AD xMenu, this script was incorporated to allow menu to pass over select boxes and similar windowed controls.

It worked so good, and was so easy to implement it for any layer, that I moved it to separate script and added few bits to ease-off integration with other scripts.

What’s it for?

Take a look at this example. Maroon layer is absolutely positioned and it goes over select box.

over drawn

...

Did I say over?

In the old days, when there was nothing dynamic about HTML, browser makers used OS controls to draw HTML form elements. That means that they were at the “lower-level” compared to HTML browser engine and was thus untouchable for web authors. This was most obvious in revolutionary IE4. Microsoft changed this in IE5 (all form elements but drop-downs), further enhanced it in 5.5 (iframes were also moved to HTML engine); other newer browsers followed similar path.

If you are using Gecko-based or Opera 7 browser, then you don’t see a need for this script (as everything is displayed correctly for you). Same goes for Safari, as I hear. But you are a very small minority. Regular Windows users (those that we make websites for), use IE. And IE still uses OS control for one form element: select list (aka drop-down box).

So in IE, drop-down punch through the layer.

This script uses one fine trick to overcome this problem. (Danger ahead: in the following text, I will identify term browser with IE).

IE "phone-book"

This one’s very bad one.

If you load up this page you’ll see a layout which has this structure:

example layout structure - gecko/khtml/opera display

  • relatively positioned list, id=“topnav”

  • static div below it

  • relatively positioned div, id=“content”, which has some example content

In Mozilla, it apears as you (or at least I) would expect - menu goes above the remaining text. In IE, it goes below the Help section text, for reasons I thought had something to do with float + position:relative combo.

example layout structure - IE display

Real reason was this: when you define block element to be position:relative (content in my test case) this will not only reset the coordinate system for its child elements, it will also create a whole new dimension for z-index. Thus, an absolutely positioned element in the body with z-index: 400 (or I assume any other number) will go below the absolutely positioned (or floated) block with z-index:1 in the content div.

Update: I’m wrong here: new z-index context (dimension) will be created only if z-index is non-auto. Declaring only position:relative will not create new context.

This goes on for as much relative divs you have. In my example, content of 2nd relative block element was showing above the content of the 1st relatively positioned.

I named it after Michael Landis’s explanation on css-discuss list, who suggested that each pos:rel marks the beggining of the new set of pages, all above the previous ones.

Solution?

Whatever you come up with. I chose not to use position: relative in the dynamic drop-down menu I was building (and encountered this).

And now, the funniest thing: IE’s behavior is by-the-book (thanks to Big John who pointed this out to me). Yes, this is how W3C specs say it must work. I must admitt that I can’t see when would one want this to behave in this manner. But I can also just be grumdgy.

Bah…every day you learn something new.

No spans. IE z-index thingie fixed.

At the original post for AD xMenu, I stated that main UL element must have position:relative. This created simplest possible solution, as it defined new coordinate system for submenus (which are absolutely positioned) and allowed me to use simple xLeft and xTop.

What I wasn’t aware of is that position:relative in IE also creates another “dimension” for z-index. After 5 days of trying this and that (I falsely accused floats as the source of problem), a good weekend spent with a girlfriend probably relaxed me enough to try something different and find a solution.

So now, ADxMenu 1.4 has a mandatory rule that you should not make your main list relatively positioned. This now means that submenu positions are calculated using xPageX and xPageY, which took few hours of testing to make sure it doesn’t break under any (yeah, right) circumstances.

Another improvement is that I removed all spans inside of A elements, which means we now have beautyful, simple unordered list of links.

Multiple, synchronous, onload functions

There’s not a single serious web site I did, where I haven’t combined two or more scripts. Calendars, DHTML layers, cookies…they all have one thing in common - they want to grab window.onload for them self.

I usually dealt with that by changing the onload function for last loaded script. This was a pain when for some reason I needed to change the loading order.

When I got tired of it, I wrote a custom script, that’s loaded before all others, and gathers all of them into one piece.