Hyperlink in absolute div fails; standalone doesn't

As an alternative to floating and margins to get the column layout I want, I began fooling around with absolute and realtive positions. However, that seems to disable the anchor (a href=“”) links.

Here’s the XHTML excerpt

<body>
<p><a href="rates.html">rate sheet</a></p>  <!-- this link works -->
	<div id="wrapper">
(snip)
		<div id="nav">
			<div id="menu">
				<ul>
					<li>HOME</li>
(snip)
					<li><a href="rates.html" name="rates" title="rates for standard services">rate sheet</a></li>
<!-- the above link does not work -->

Here’s the CSS excerpt

<!--
/* centering the wrapper in the screen */
		body {
			margin: 0px;
			padding:0px;
			text-align:center;
			background-color: rgb(245, 200, 156);
			color: rgb(138, 69, 0);
		}
		
		#wrapper {
			position: relative;
			top: 0px;
			left: 0px;
			width:800px;
			height: 600px;
			background-color:rgb(255, 217, 179);
			z-index: -1;
			margin: 0 auto;
			text-align:left;
			padding:0;
		}
		#nav {
			position: absolute;
			top: 0px;
			left: 76px;
			width: 125px;
			height: 600px;
			background-color:rgb(202, 101, 0);
			color: rgb(255, 186, 117);
			font-weight: bold;
			z-index: -1;
			padding:0;
		}
		#menu {
			position: absolute;
			top: 275px;
			left: -12px;
			height: 365px;
		}
		#menu a{
			color: rgb(255, 186, 117);
		}
		#menu ul {
			list-style: none;
		}


What references I read in this forum and others says something about the anchor itself being positioned. Very confusing.

Apparently this has to do with z-index of the anchor within the menu div. I’ve tried altering the z-indicies but it screws up the other blocks. (IE, for once, doesn’t have this problem). Remember the good old days of table layouts?

So I guess I’ll go back to the slings and arrows of outrageous floats and margins.

crap.

Here’s the answer (from css-discuss.incutio), but I don’t understand what I’ve bolded in the quote below;

First, you say that the element is in front or behind other elements that share the same stacking context. This is what we normally think about when we change z-index – we want something to move in front or in back of something else.

Second, you create a new stacking context for anything inside the positioned element. Once you’ve created a stacking context, any layering that happens inside that stacking context stays in that context. This is the part we forget.

One of the tricky things is figuring out which context two tags share. In a normal document, without any positioning, the document has exactly one stacking context – the one created by html:

My anchor path is (the css is after I’ve fooled around with it – original is in first post)
wrapper (position: relative; z-index: -1;)
nav (position: absolute; z-index: 4;)
menu (position: absolute; z-index: -1)
ul (position: absolute;)
li
a (z-index: 1)

Hi,

The problem is actually with your wrapper and the negative z-index on the wrapper puts the foreground content behind whatever is behind the header and therefore cannot be clicked. Ultimately its the positioned parent that controls the ‘atomic’ stacking levels of all its children.

Here’s a shortened demo showing the problem.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style>
.test {
	background:red;
	width:300px;
	height:300px;
	position:relative;
	z-index:-1;
}
a:hover { background:#fff }
</style>
</head>

<body>
<div class="test"><a href="#">Link Test</a></div>
</body>
</html>


In all browsers except IE the above link is not clickable.

You will rarely need to use negative z-index as stacking levels can be controlled from zero and upwards so just don’t use them. Just change the two negative z-indexes to zero and the link will work. If the parent element needs to be behind other elements then set the z-index higher on the other elements.

Apart from some special tricks there will be no need to set the z-index to less than zero and certainly not for a parent wrapper which risks putting it behind the body in some older browsers.