gibatronic gibatronic - 11 months ago 91
CSS Question

z-index chrome bug

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:


<div id="mask">

<div id="box">
<div class="below-mask circle">
should be below the mask

<div class="above-mask circle">
should be above the mask


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;


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!


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:

  • document root (z-index 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.