by Kyle Weems 17.April 2008 11:45
About the only newsworthy thing that I've seen in the web development world this week has been FOWD, a web development conference in the UK. As I'm not currently drinking warm beer, eating fish and chips, and... uh... failing to drive on the correct side of the street, it's safe to say that I in fact am not in England at this very moment. So the only comment I can think to offer about that event is that their website is rather pink, isn't it?
Not that there's anything wrong with that. It's just very 80's. The bad neon kind of 80's that involved cocaine, Miami cops in speedboats, and really bad hair.
However, in honor of my British compatriots in the web development business, I'll be discussing one of the more frustrating properties to work with in CSS: z-index. I'll be thinking "zed" when I write z, though, not "zee". I can't count the number of times I was almost accosted by angry Canadian or British developers over that point at the WDN conference I went to in Vancouver in January. So "zed" it is.
I also might be eating some fish and chips today, but I doubt that's worth a detailed discussion.
Ok, it's worth a quick note at least. What's with the obsession with cod, people? Seriously. Yes, it's cheap. But that doesn't mean it's delicious. Go for salmon, or halibut, or anything other than the great white filler of the sea.
The z-index property appears fairly straightforward and handy. When a box (aka an element, aka part of a web page [the acronym "aka" starts to look really funny after a while]) is assigned a z-index value (any integer, positive or negative), it makes that box closer or farther from the viewport from the perspective of the site visitor. So if you've got a design with overlapping elements (all to common in the modern world of web design), z-index is priceless in making sure that the right item appears on top.
So if you've got two items that are overlapping, and you assign the item you want to be on top the higher z-index value, that one will be on top, right?
Not neccesarily. Take a look at example 1. If you look at the page source (complete with CSS) you'll note that the h1 tag inside the first div has been given z-index: 10 and the h2 tag inside the second div has z-index: 1. So why is the h2 showing up, and not the h1?
We've reached our first annoying little detail. In order for z-index to work, it needs to be on a positioned element. More specifically, it needs to be on an element that has either the relative, absolute, or fixed position types. The default static position won't work. I'm not really sure why they decided that z-index should never work on a static element. There's probably plenty of good technical reasons, but the end result is the same: confusion for the novice CSS designer. I can't count the number of times I've done something that I knew should work but failed to have any visual effect, only to later realize there was one tiny catch.
Fortunately, the solution is incredibly easy. Add a position type. In example 2, I've added position: relative to both the h1 and the h2. If you view the example in any browser other than Internet Explorer, it'll show as we've been expecting. The h1 is on top and visible, not the h2.
So what's going on with IE? Well, first, as I've previously established, that browser's standards compliance is mangled at best, even in IE7 (which is admittedly way better than the animate nightmarish corpse called IE6 that still plagues the developer countryside with its ghoulish howls and jerky movements). For reasons well beyond me, Microsoft decided to implement z-index in a special way.
No, not the good kind of special.
In addition to a few other bugs with z-index, the biggest problem IE presents is as follows (quoted from SitePoint's CSS Reference): "Internet Explorer for Windows versions up to and
including 7 always use the nearest positioned ancestor to determine the
stacking context for the element in question."
In English this means that if two elements with a z-index value have different parent elements, then the z-index value only matters in relation to their parents, and not each other.
Yes, this is more proof that Microsoft hates us.
Although I have hope that IE8 (which looks to be a lot farther along the standards compliance trail) will do things right, until IE6 and IE7 become obsolete we'll have to code around this limitation. So what do we do?
Examine example 3. It looks correct in all the major browsers, including IE. What we did was moved the z-index values to the divs that the h1 and h2 are in. Since those divs have the same positioned parent (the body tag), their z-index values will stack in relation to each other in IE.
This does mean that we're going to have several potential layout concepts that will face issues in regards to z-indexing when IE is involved. Nothing you can't be creative about, but it's worth considering when you're doing the html for a site. Yes, presentation and layout are supposed to be completely seperate in an idea world. But in an idea world we'd have robot maids and flying cars. So if two elements have to have z-index properties to stack properly in your design, make sure they've got the same positioned ancestor.
Is it just me, or does "Positioned Ancestor" sounds like a dead relative with connections? You know, like a great-grandfather who can get you a discount on ectoplasm? Hmmm, that might make a good band name.