I'm experiencing a really annoying bug that seems to only happen on Windows and OS X: the z-index of an element whose parent has fixed position doesn't work on Chrome! I converted my odd situation to a simple code:
html:
<div id="mask">
</div>
<div id="box">
<div class="below-mask circle">
should be below the mask
</div>
<div class="above-mask circle">
should be above the mask
</div>
</div>
css:
body {
font-family: Verdana;
font-size: 9px;
margin: 0px;
}
#box {
position: fixed;
}
#mask {
position: absolute;
left: 0px;
top: 0px;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
z-index: 9998;
}
.circle {
position: relative;
background-color: rgba(255, 204, 0, 0.75);
border-radius: 75px;
line-height: 150px;
margin: 50px;
text-align: center;
width: 150px;
height: 150px;
}
.above-mask {
z-index: 9999;
}
.below-mask {
z-index: 9997;
}
sandbox: http://jsfiddle.net/gibatronic/umbgp/
I tested on Internet Explorer 9, Firefox 15, Opera 12.02 and Safari 5.1.7 on OS X and Windows and all of them displayed as expected. I also tested on Ubuntu 12.10 and it worked just fine for every browser including Chrome! I even tested on Kindle 4 browser and it worked!
I wonder if anyone knows any kind of fix to workaround this issue!
To sum up, most issues with z-index can be solved by following these two guidelines: Check that the elements have their position set and z-index numbers in the correct order. Make sure that you don't have parent elements limiting the z-index level of their children.
z-index only works on positioned elements (relative, absolute, fixed, sticky) so if you set a z-index on an element with a static position, it won't work.
In CSS code bases, you'll often see z-index values of 999, 9999 or 99999. This is a perhaps lazy way to ensure that the element is always on top. It can lead to problems down the road when multiple elements need to be on top.
If the z-indices aren't changing often, the performance hit probably won't be noticeable at all. Even if you are changing the z-indices a lot, sorting a list of 15 items is almost instantaneous.
one800higgins's answer is along the right lines. The real answer is that on mobile WebKit and Chrome 22+, position: fixed
always creates a new stacking context, even when z-index
is auto
. So the stacking context hierarchy looks like this:
0
)
#mask
(z-index 9998
)#box
(z-index 0
)
.above-mask
(z-index 9999
).below-mask
(z-index 9997
)That means that 9998
is never compared with 9999
or 9997
to determine stacking order. Instead, 9999
is compared with 9997
to determine which of .above-mask
and .below-mask
is further in front, and then once everything inside #box
is stacked in that context, it's treated as a single layer at z-index 0
which gets stacked behind #mask
at z-index 9998
.
This also explains why @TheNextBillGates's answer of moving #mask
inside #box
works - because then #mask
is in the same stacking context as .above-mask
and .below-mask
. I highly recommend the above link for more comprehensive details, and you should also see the announcement for the stacking change for fixed
elements in Chrome.
I just came across this bug, and its still happening in Google Chrome v26. I could set the z-index as high as I wanted to from code or Chrome's CSS editor and it made no difference (and the element's position was set to absolute). The same z-index setting was working as expected in Firefox and even IE8-IE10. When I switched the parent element from position:fixed to position:absolute then the child element's z-index worked fine in Chrome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With