z-index changes the stacking order or layering of positioned elements. If no element is positioned then the stacking order gets higher, closer to the front, for each descendant.

Each positioned element that has been assigned a z-index other then auto, creates a stacking context, which may be easier to explain in another context lets use a sandpit. The sandpit is positioned absolutely so the children don't move it an make a bigger mess and has a z-index of 1.
Inside the sandpit we have other containers, buckets etc. which in this example are relatively positioned. Lets start with three buckets, red green and blue. The buckets all have the same z-index and they are all displayed at the same level. If you put the green bucket inside the red bucket, then the blue and red buckets are at the same level and the green is at a higher level even though they still have the same z-index. That is because a new stacking context is created each time you position and assign a z-index.

So if the green bucket had a couple of plastic cups (glass could be dangerous) in it and they were positioned, then any z-index assigned to the cups are only relevant withing the green bucket or stacking context. The elements within the green bucket have their own playing area and don't have to
worry about the z-index of elements outside the bucket and can start a new stacking context from zero.

Ok it's 2:45 am here so I shouldn't really be playing in the sandpit so lets go indoors and play with our browsers. Did anyone say IE, yes you guessed it IE does some wacky things that make positioning more difficult then it should be. Remember how a new stacking context is created each time an element is positioned (relative or absolute) and given a z-index other then auto. IE likes to be different and creates a new stacking context every time and element is positioned, z-index is not required.

IE has some other bugs which affect things such as floats, and one of the fixes I use is to apply position relative to all floated elements. Position relative should be ignored when an element is floated so it causes no harm to other browsers and helps fix a couple of problems. Now lets say we have a page with a header and two floated columns. The header is positioned relative, inside the header we have a drop down menu which is also positioned relative. If we give the menu a z-index we should be able to display it higher then the columns thanks to the assigned z-index. Unfortunately the columns which are relatively positioned to fix other issues, are not playing nicely. The drop down menu when active displays under the columns in IE. To fix it you can assign each element with position set to relative or absolute, a z-index. In our example if you set the z-index of the header higher then the columns everything should be apples.

Form elements live in a galaxy all of there own and don't play nicely with z-index.
If you are having problems displaying something, lets say a drop down menu over a form element such as a input field you may be best hiding the input field while the menu is above it.

Here is an example page to play with.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> 
<style type="text/css">
#header{height:50px; position:relative;}
#left{float:left; width:30%; position:relative; height:50px; background-color:red; }
#right{float:left; width:65%; position:relative; height:50px; background-color:blue; }
li ul{display:none;}
#menu{position:absolute; z-index:100;}
</style>
<script type="text/javascript">
window.onload=function(){
	var menu=document.getElementById("menu");
	var inli=menu.getElementsByTagName("LI");
	for(var x=0; x < inli.length; x++){
		inli[x].onmouseover=function(){
			this.getElementsByTagName("UL")[0].style.display="block";
		}
		inli[x].onmouseout=function(){
			this.getElementsByTagName("UL")[0].style.display="none";
		}
	}
}	
</script>
</head>
<body>
<div id="header">
<ul id="menu">
	<li>menu<ul>
		<li> item #1</li><li> item #2</li><li> item #3</li><li> item #4</li><li> item #5</li><li> item #6</li><li> item #7</li><li> item #8</li>
	</ul></li>
</ul>
</div>
</div>
<div id="left"> </div>
<div id="right"> </div>
</body>
</html>

IE FIX: relative position on floated elements

"one of the fixes I use is to apply position relative to all floated elements"

Thanks Tony, this is EXACTLY what I was looking for!

Cheers,
g