Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webkit-transform breaks z-index on Safari

Problem

I'm trying to make a layer appear like it's a wall falling down, revealing the layer behind it. I've setup two fixed div positions. The "Wall" div has a z-index of 9999, the "Background" div has a z-index of 0;

In Webkit browsers (Safari/IOS) that I've tested, it seems like once the animation starts on the "wall", the z-indexes are lost or ignored, causing the "wall" layer to abruptly disappear behind the background div.

Any ideas on how to preserve the z-indexes of the layers? Thanks in advance!

Example Code (note: jsFiddle at the bottom)

HTML Code

<div id="wall">
    This is the wall
</div>

<div id="background">
    This is the background
</div>

<button id="start" style="float: right;">
Flip Down
</button>

Some javascript to enable the button

$('#start').click(function(){
    alert('Should Fall Down like a wall, revealing the background');
    $('#wall').addClass('animated flipDown');
});

CSS Code (cribbed from animate.css)

#wall{
    background-color: #F00;
    width: 100px;
    height: 100px;
    position:fixed;
    top:0;
    left:0;
    z-index: 9999;
}

#background{
    background-color: #00F;
    width: 100px;
    height: 100px; 
    position:fixed;
    top:0;
    left:0;
    z-index: 0;
}

.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}


/*** flipDown ***/

@-webkit-keyframes flipDown {
  0% {
    -webkit-transform: perspective(400px) rotateX(0deg);
    transform: perspective(400px) rotateX(0deg);
    -webkit-transform-style: flat;
    opacity: 1;
  }

  100% {
    -webkit-transform: perspective(400px) rotateX(90deg);
    transform: perspective(400px) rotateX(90deg);
    -webkit-transform-style: flat;
    opacity: 1;
  }
}

@keyframes flipDown {
  0% {
    -webkit-transform: perspective(400px) rotateX(0deg);
    -ms-transform: perspective(400px) rotateX(0deg);
    transform: perspective(400px) rotateX(0deg);
    opacity: 1;
  }

  100% {
    -webkit-transform: perspective(400px) rotateX(90deg);
    -ms-transform: perspective(400px) rotateX(90deg);
    transform: perspective(400px) rotateX(90deg);
    opacity: 0;
  }
}

.flipDown {
    -webkit-animation-name: flipDown;
    animation-name: flipDown;
    -webkit-backface-visibility: visible !important;
    -ms-backface-visibility: visible !important;
    backface-visibility: visible !important;
    -webkit-transform-origin: bottom;
    -ms-transform-origin: bottom;
    transform-origin: bottom;
}

jsFiddle

http://jsfiddle.net/3mHe2/2/

Check out the differences in Safari vs Chrome.

like image 992
zeroSkillz Avatar asked Mar 24 '14 22:03

zeroSkillz


People also ask

Does transform affect Z-index?

Bookmark this question.

Why is Z-Index not working?

You set z-index on a static element By default, every element has a position of static. 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.

Does Z-Index work on static?

z-index only affects elements that have a position value other than static (the default). Elements can overlap for a variety of reasons, for instance, relative positioning has nudged it over something else. Negative margin has pulled the element over another. Absolutely positioned elements overlap each other.

Does Z-Index inherit?

No, it isn't inherited. You can see it in MDN article. However, be aware that z-index sets the z-position relatively to the stacking context. And a positioned element with non auto z-index will create an stacking context.


3 Answers

My rotating element wasn't suitable to have a neighbour to the background, but I fixed it by applying

transform: translateZ(1000px);
transform-style: preserve-3d;

to the parent of the rotating element. Safari now thinks it's 1000px infront of the background.

like image 173
Kit Sunde Avatar answered Sep 21 '22 20:09

Kit Sunde


Found a solution. Hopefully this helps someone in the future.

It turns out that there is a "bug" in the safari versions of webkit. When a 3d css animation is playing, the original z-indexes are lost. Instead, it seems like the animating pieces are put into a separate z-index "group" that is separate from the rest of the z-indexes of the DOM.

The solution is to join the backdrop div and the wall div into the same z-index group by wrapping it in a div with a webkit-transform that doesn't change anything. That causes the backdrop and wall to be children of the wrapper div and the z-indexing of the respective children are preserved.

<div id="wrapper" style="-webkit-transform: translate3d(0px, 0px, 0px);">
    <div id="wall">
        This is the wall
    </div>

    <div id="background">
        This is the background
    </div>
</div>

I believe it is the same or similar issue to this:

css z-index lost after webkit transform translate3d

like image 36
zeroSkillz Avatar answered Sep 20 '22 20:09

zeroSkillz


I ran into this issue and nothing would fix it until i added perspective to the parent container of the item that should be behind.

.wrap{
    perspective: 1000px;
}
like image 37
pizzarob Avatar answered Sep 20 '22 20:09

pizzarob