z-index chrome bug

13,794

Solution 1

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.

Solution 2

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.

Solution 3

If you move the #mask inside of the #box it works just fine.

<div id="box">
    <div id="mask">&nbsp;</div>
    <div class="below-mask circle">should be below the mask</div>
    <div class="above-mask circle">should be above the mask</div>
</div>

Here's a fiddle http://jsfiddle.net/TheNextBillGates/jKm4b/

Not sure why this is just yet.

Share:
13,794
gibatronic
Author by

gibatronic

Programmer, cyclist and beer lover from Brazil 🇧🇷

Updated on June 04, 2022

Comments

  • gibatronic
    gibatronic almost 2 years

    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">
        &nbsp;
    </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!

  • Eric MORAND
    Eric MORAND over 10 years
    Very good explanation and thanks for the link. This is not a bug as I've always thought it was ! You made my day.
  • gibatronic
    gibatronic almost 8 years
    that would be a workaround, not really nice to have to recover to js to solve it, I was more interested in a solution for the z-index stack problem, but as the accepted answer points out, it was wrong what I was trying to achieve.