1

I am creating tabbed menu with SVG images as background. I need the the tabs to overlap each other in reverse order - first over second, second over third. And I need svg shadow, to work in Firefox.

Howerer, when I apply the shadow, the z-index of .after element gets broken which breaks the overlap. Is there any way to change stacking order/fix this? Here is sample source:

div{
    background-color: grey;
    padding-top:20px;
    padding-bottom: 20px;
}
ul.tabs-nav{
	margin: 0px;
	padding: 0px;
	list-style-type: none;
	margin-left: 10px;
	height: 40px;
	overflow: hidden;
}
ul.tabs-nav li{
	margin: 0px -38px 0px 0px;
	padding: 0px;
	display: block;
	float: left;
	text-decoration: none;
	filter: url("#drop-shadow");
}
ul.tabs-nav li a{
	background-color: #5d6c7a;
	text-decoration: none;
	height:40px;
	line-height: 40px;
	float:left;
	color: white;
	font-size: 14px;
	vertical-align: baseline;
	padding-left: 10px;
	padding-right: 10px;
}

ul.tabs-nav span.before{
	background-image: url("https://dl.dropboxusercontent.com/u/10056766/fiddle/tab_grey.svg");
    background-position: left top;
	display: block;
	float: left;
	height: 40px;
	width: 40px;
	position: relative;		
}

ul.tabs-nav span.after{
	background-image: url("https://dl.dropboxusercontent.com/u/10056766/fiddle/tab_grey.svg");
    background-position: right top;
	display: block;
	float: left;
	height: 40px;
	width: 40px;
	position: relative;
	z-index:1;
}

ul.tabs-nav li:first-child span.before{
	background-image: url("https://dl.dropboxusercontent.com/u/10056766/fiddle/tab_white.svg");
    background-position: left top;
	display: block;
	float: left;
	height: 40px;
	width: 40px;
	position: relative;		
}

ul.tabs-nav li:first-child span.after{
	background-image: url("https://dl.dropboxusercontent.com/u/10056766/fiddle/tab_white.svg");
    background-position: right top;
	display: block;
	float: left;
	height: 40px;
	width: 40px;
	position: relative;
	z-index:1;
}

ul.tabs-nav li:first-child a{
    background-color: white;
    color: black;
}
<div>
<ul class="tabs-nav" style="padding: 0;">

	<li style="z-index: 10;" class="tab
	tabs-active
	"><span class="before"></span><a href="/foo.jsp" class="">User</a><span class="after"></span></li>
	<li style="z-index: 8;" class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Developer</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Users</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Roles</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Attributes</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Screens</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Locales</a><span class="after"></span></li>
	<li class="tab
	"><span class="before"></span><a href="/foo.jsp" class="">Providers</a><span class="after"></span></li>
	</ul>
    
</div>

<svg height="0" xmlns="http://www.w3.org/2000/svg">

<filter id="drop-shadow">

<feGaussianBlur in="SourceAlpha" stdDeviation="2.2"/>

<feOffset dx="12" dy="2" result="offsetblur"/>

<feFlood flood-color="rgba(0,0,0,0.2)"/>

<feComposite in2="offsetblur" operator="in"/>

<feMerge>

<feMergeNode/>

<feMergeNode in="SourceGraphic"/>

</feMerge>

</filter>

</svg>

http://jsfiddle.net/mark_bacon/5vnefef5/3/

Turn off filter of li element and you will see how it should look.

1 Answer 1

4

The filter property creates a CSS stacking context. That means that the z-index property on any child elements will only control how the child content is stacked amongst each other, not how they are stacked relative to other elements on the page.

You're applying filter to your li elements, but you're applying the z-index to the child spans. This will raise up those spans above the other content in the li, but all the content within the list element will be flattened into one layer before being stacked with the rest of the page. And since you don't set a z-index value on the li itself, the default stacking order applies. In other words, elements later on in the document get drawn over top.

You've got a lot of things going on in this example, but I'm pretty sure you could get the effect you want just by setting z-index:1 on the li:first-child itself.

4
  • Thank you for explanation. I got lost in the stacking order. But I added position:relative to every li element and decreasing z-index values for tabs from first to last. Now everything works great.
    – kvgr
    Commented Dec 23, 2014 at 13:09
  • Hello Amelia. I read this answer multiple times, I knew all this before I read it, but still, I have NO IDEA why element on my site is not working. I'm really sorry for asking all this in comment, but you are my last hope :) codepen.io/suez/pen/3d49b2d6681dac2d87984aa57e55d503 - here is a pen, and on first page I have .scroll-down white circle with position fixed and his parent element with SVG filter (gooey effect). Everything works perfectly in Chrome/IE, but in FF this element is invisible. I tried everything, all possible z-index combinations. It's possible to fix this in FF? :( Commented Apr 27, 2015 at 19:18
  • Turns our that: 1) If SVG with filter definition inside has display: none in FF, then child of an element with this filter applied will not be visible on any condition. But you will be able to click it, like his z-index is ok. 2) And no matter how hard you try, you won't be able to see and interact with element, which has position: fixed inside element with svg filter applied in Firefox :( Commented Apr 27, 2015 at 20:05
  • @NikolayTalanov Firefox has had problems in the past where display:none interferes with re-using content. It's possible that filters are still problematic. Maybe try CSS absolute positioning to hide your definition SVG, to see if that was the problem? More generally, any browser, if there is an error on the filter, the shape gets replaced by a transparent region, which is what you're seeing. However, pointer event click regions aren't affected by filters or masks, which is why it can still be clicked.
    – AmeliaBR
    Commented Apr 28, 2015 at 21:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.