7

I'm trying to have a sidebar menu overlap a content div, where the active menu item appears over the div and the non-active items would appear under. The intersection between a ul and div would be small, but the interleaving effect would create an illusion of depth.

I understand that z-index only applies to sibling elements. So the following doesn't work:

#menu {z-index:0}
#menu li.active {z-index:2}
#content {z-index:1}
<ul id="menu">
  <li class="active">Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<div id="content">Side content</div>

Is there a good way to do this without having to make each menu item a div on the same level as #content?

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • I don't think you could get this working at all without completely mangling your markup and introducing complicated CSS - keep it simple, dude. – Sam Jul 15 '09 at 00:38

4 Answers4

2

You want some li to appear at the front of a div, and the other ones at its back.

The only way to achieve this is making sure all the li and the div belong to the same stacking context. That means the ul must not create any stacking context, so don't set any z-index to it. See Which CSS properties create a stacking context? for what exactly should be avoided.

And then it will be easy: just set the z-index properties to the li and the div as desired. However, remember that z-index only applies to positioned elements, e.g. position: relative.

#menu > li.active {
  position: relative;
  z-index: 2;
}
#content {
  position: relative;
  z-index: 1;
}

body {
  margin: 8px;
  position: relative;
}
#menu {
  margin: 0;
  padding: 5px 0;
  list-style: none;
}
#menu > li {
  padding-left: 15px;
  border: 1px solid;
  background: yellow;
  margin: 4px 0;
}
#menu > li.active {
  position: relative;
  z-index: 2;
}
#content {
  position: absolute;
  background: blue;
  top: 0;
  left: 5px;
  width: 5px;
  height: 100%;
  z-index: 1;
}
<ul id="menu">
  <li class="active">Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<div id="content"></div>
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
0

Rather than messing with z-indices and hairy CSS hacks, may I suggest using some background tricks? One thing you can do is to give the menu a repeating background so that a portion of it APPEARS to be part of the content div. Then the active item can have a background that appears to extend into the content. This is much simpler and avoids a lot of headaches.

pegasus4747
  • 291
  • 1
  • 3
0

I suggest instead of using z-index to do this, try setting the widths of the li items based on whether they are active or not. If you make the side bar navigation flush with the content div, you could then feasibly make the .active li slightly wider so that it overlaps the content div. This way it will look like the non-active part of the menu is under the content div. If I'm not understanding your idea correctly perhaps you could show me an example. Good luck, sounds like a nifty effect.

Anon
  • 5,103
  • 11
  • 45
  • 58
0

give the li a z-index instead of the #menu:

#menu li {z-index:0}
#menu li.active {z-index:2}
#content {z-index:1}

And don't forget to position them relative for the z-index to take effect.

Thomas Maas
  • 1,999
  • 12
  • 8