This is not actually a z-index problem. I’m saying that right up front only because we spent SO much time thinking it was.
Scenario:
You have a fly out nav menu (ul, li) that you dynamically (javascript) show via a css display: none/block.
Problem: For some reason the menu that you flyout renders underneath (z-index) the content you have in the div below the menu. WTF???
After beating our heads against this for a few days we finally realized that this was because the content that was rendering over the dynamic menu had its “position” set to “relative” in its css class.
I apologize for the length of this example but the markup is important to demonstrate the issue. <see code below >
FIX: now, remove the “position:relative” from the horkedDiv css class and it works…
It appears that elements which have a position set to relative will win in z-index over ones that have a "display none/block" settings that is dynamically set.
I hope this helps someone!
-SteveM
P.S. This example also shows an implementation of a client side(javascript) menu control. (Thank you Robb Charnock!)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server"><title></title>
<style type="text/css">
.horkedDiv
{
position:relative;
height: 12px; padding: 16px 0px 20px 15px; border-bottom: solid 1px #cbd7e0; font-size: 1.4em; background-color: #f3f2f2;color: #4f5761;
}
body {width: 100%;line-height: 1.55em;background-color: #c0d3e0;}
div.header {position: relative; width: 100%;height: 45px; background-color: #f3f2f2; color: #4f5761; }
div.main {width: 989px; min-height: 400px; margin: auto; margin-top: 34px; background-color: transparent; background-repeat: repeat-y; background-position: right; }
div.content {float: left; width: 983px; min-height: 654px; padding: 0px 0px 4px 0px; margin-left: 3px; background-color: #fff; }
div.navContainer {width: 983px; margin-top: 0px; margin: auto; margin-bottom: 30px; padding-top: 13px;}
div.navContainer ul.mainHeader { list-style-type: none; float: left; margin: 0px; width: 420px; }
div.navContainer ul li ul { display: none; top: 30px; width: 124px; margin: 0px; padding: 0px; background-color: #a2a4a7; }
div.navContainer ul li.support ul {list-style-type: none;}
div.navContainer ul li ul.showSubNav {position: absolute; display: block; }
div.navContainer ul li ul li:hover {background-color: #f3f2f2;}
div.navContainer ul li ul li a { display: block; width: 100%; padding: 5px; width: 105px;}
div.navContainer ul li a, div.navContainer ul li a:visited {color: #4f5761; text-decoration: none; text-transform: uppercase;}
.showSubNav{display:block;}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"/>
<script type="text/javascript">
GlobalHeader = function(element)
{
this._elementsWithEvents = new Array();
this._openSubNav;
this._menuShowing = undefined;
this._menus = new Array();
GlobalHeader.initializeBase(this, [element]);
}
GlobalHeader.prototype = {
initialize: function()
{
$addHandler(document, 'click', Function.createDelegate(this, this.DocumentClick));
this.AddMenu('GlobalHeader');
},
dispose: function()
{
var elements = this.get_ElementsWithEvents();
for (var i = 0; i < elements.length; i++)
{
Sys.UI.DomEvent.clearHandlers(elements[i])
}
GlobalHeader.callBaseMethod(this, 'dispose');
},
AddMenu: function(menuId)
{
var navElelment = $get(menuId);
for (var i = 0; i < navElelment.childNodes.length; i++)
{
var childNode = navElelment.childNodes[i];
if (childNode.tagName != undefined)
{
if (childNode.tagName.toLowerCase() == 'li')
{
if (childNode.getElementsByTagName('ul').length > 0)
{
$addHandler(childNode, 'click', Function.createDelegate(this, this.HandleClick));
this.get_Menus().push(childNode);
}
}
}
}
},
HandleClick: function(event)
{
var subNavUls = event.target.parentNode.getElementsByTagName('ul');
if (this.get_MenuShowing() == subNavUls[0])
{
this.closeMenus();
this.set_MenuShowing(undefined);
} else if (subNavUls.length > 0)
{
this.set_MenuShowing(subNavUls[0]);
this.closeMenus();
this.toggleCurrentMenu(event.target);
event.stopPropagation();
event.preventDefault();
// return false, prevent event propagation
return false;
}
// return true, allow event to propagate
return true;
},
DocumentClick: function(event)
{
if (this.get_MenuShowing() != undefined)
{
this.closeMenus();
this.set_MenuShowing(undefined);
}
},
toggleCurrentMenu: function(element)
{
if (this.get_MenuShowing() != undefined && this.get_MenuShowing != element)
{
Sys.UI.DomElement.toggleCssClass(this.get_MenuShowing(), 'showSubNav');
}
},
closeMenus: function()
{
var menusLength = this.get_Menus().length;
for (var i = 0; i < menusLength; i++)
{
var liElement = this.get_Menus()[i];
var ulElements = liElement.getElementsByTagName('ul');
var length = ulElements.length;
for (var j = 0; j < length; j++)
{
Sys.UI.DomElement.removeCssClass(ulElements[j], 'showSubNav');
}
}
},
get_ElementsWithEvents: function(){return this._elementsWithEvents;},
set_ElementsWithEvents: function(elementsWithEvents){this._elementsWithEvents = elementsWithEvents;},
get_OpenSubNav: function(){return this._openSubNav;},
set_OpenSubNav: function(openSubNav){this._openSubNav = openSubNav;},
get_MenuShowing: function(){return this._menuShowing;},
set_MenuShowing: function(menuShowing){this._menuShowing = menuShowing;},
get_Menus: function(){return this._menus;},
set_Menus: function(menusg){this._menus = menus;}
}
GlobalHeader.registerClass('GlobalHeader', Sys.UI.Control);
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
var pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
pageRequestManager.add_pageLoaded(initHeader);
function initHeader()
{
var _globalHeaderControl;
_globalHeaderControl = $create(GlobalHeader, null, null, null, $get('GlobalHeader'));
}
</script>
<div class="header">
<div class="navContainer">
<ul id="GlobalHeader" class="mainHeader">
<li class="support"><a href="#">Links</a>
<ul>
<li><a href="http://www.lunarlabs.com/">Lunarlabs</a></li>
<li><a href="http://www.telerik.com/">Telerik</a></li>
<li><a href="http://www.codeproject.com/">CodeProject</a></li>
<li><a href="http://www.theonion.com/">The Onion</a></li>
<li><a href="http://antwrp.gsfc.nasa.gov/apod/">Astronomy Picture of the Day</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="main">
<div class="content">
<div class="horkedDiv">
This div shows over the nav menu when the position is set to relative</div>
</div>
</div>
</form>
</body>
</html>
z-indexrelative positioningclient side navigation menuz-index problem
None
0 Points
1 Post
Position:relative / z-indix-ish problem
Dec 12, 2008 05:22 PM|stevem@lunarlabs.com|LINK
This is not actually a z-index problem. I’m saying that right up front only because we spent SO much time thinking it was.
Scenario:
You have a fly out nav menu (ul, li) that you dynamically (javascript) show via a css display: none/block.
Problem: For some reason the menu that you flyout renders underneath (z-index) the content you have in the div below the menu. WTF???
After beating our heads against this for a few days we finally realized that this was because the content that was rendering over the dynamic menu had its “position” set to “relative” in its css class.
I apologize for the length of this example but the markup is important to demonstrate the issue. <see code below >
FIX: now, remove the “position:relative” from the horkedDiv css class and it works…
It appears that elements which have a position set to relative will win in z-index over ones that have a "display none/block" settings that is dynamically set.
I hope this helps someone!
-SteveM
P.S. This example also shows an implementation of a client side(javascript) menu control. (Thank you Robb Charnock!)
z-index relative positioning client side navigation menu z-index problem