Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safari rendering bug with CSS transform - a depth sorting / z-index problem? (works in Chrome)

For my website I'm using this spiral animation: Codepen

This is how it looks like in Chrome (as it is supposed to be):

And this is how it looks like in Safari:

The css transform looks great in Google Chrome but in Safari it breaks.

I tried the following (as mentioned in other forums/threads), but without success:

transform: translateZ(0px);
transform-style: flat;
transform: translate3d(0,0,0);

Here are some similar/related questions. But after hours of searching I haven't found any solution (and yes, I tried all the answers I found):

  • Prevent Safari cuts with transform
  • Safari Rendering Issues on Rotated Elements
  • CSS transition transform z-index conflict in Safari (Works on Chrome / FF)
  • CSS Translate Issue on Safari
  • CSS transform causing div to overlap in Safari?
  • Bug in CSS3 rotateY transition on Safari?
  • Why does Safari treats transform translate different when compared to chrome?
  • Why on Safari the transform translate doesn't work correctly?
  • Safari CSS Transition flickering
  • CSS TranslateY Animation on Safari

Related Bugs?

  • https://bugs.webkit.org/show_bug.cgi?id=188656
  • https://bugs.webkit.org/show_bug.cgi?id=61824
  • https://bugs.webkit.org/show_bug.cgi?id=54766
  • https://bugs.webkit.org/show_bug.cgi?id=88587

My code is based on this blog: https://codemyui.com/spiral-banner-text-animation-using-pure-css/


Here is the code (same as here Codepen)

html:

<ul>
  <li>
    <img src="https://picsum.photos/200?random=1" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=2" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=3" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=4" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=5" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=6" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=7" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=8" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=9" />
  </li>
  <li>
    <img src="https://picsum.photos/200?random=10" />
  </li>
</ul>

stylus (css):

$lines = 10;
$duration = 4;

ul {
  perspective: 900px;
  list-style: none;
  height: 100vh;
  max-height: 800px;
  min-height: 400px;
  text-align: center;
}

li {
  position: absolute;
  top: 0;
  width: 100%;
  animation-duration: ($duration * $lines) s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-name: spiral-staircase;
  opacity: 0;
}

for $i in 0 .. $lines {
  li:nth-child({$i}) {
    animation-delay: (($duration * $i)) - $duration s;
  }
}

for $r in 0 .. ($lines / 2) {
  li:nth-child({$r}) {
    right: ($r / 2) rem;
  }

  li:nth-last-child({$r}) {
    right: ($r / 2) rem;
  }
}

@keyframes spiral-staircase {
  0% {
    transform: translateY(40vh) rotateY(-90deg);
    opacity: 0;
  }

  5% {
    opacity: 1;
  }

  45% {
    opacity: 1;
  }

  50% {
    transform: translateY(0vh) rotateY(90deg);
    opacity: 0;
  }

  100% {
    transform: translateY(0vh) rotateY(90deg);
    opacity: 0;
  }
}

It seems to be a bug in Safari. But do you guys have a workaround for? I would deeply appreciate any help!

Thank you!

Edit: If you can reproduce the question (which you should be able to do with the provided Codepen - just open the Codepen once in Chrome and once in Safari) and you don't have a solution or answer, I would appreciate an upvote for the question (so more people can see it). Because the problem with this question is: it is very specific and I guess only few people can answer it. Therefore more upvotes get this question more attention - and hopefully a solution.

like image 637
nulldevops Avatar asked Feb 20 '21 22:02

nulldevops


1 Answers

The way to work around the lack of z-index support is to avoid having the planes intersect by displacing them on the z-axis.

since we are animating the transform property and we need that property for doing the z-axis displacement we can change the animation to the img element instead of the li element, and do the displacement on the li.

here's a working example: https://codepen.io/ptcc/pen/qBqyqEj?editors=0100

the changes are basically these:

move the perspective from the ul to each li

li {
    perspective: 900px;

move the animation to the img and set a translateZ on the li based on the index.

for $i in 0 .. $lines {
  li:nth-child({$i}) {
      transform: translateZ($i*100px);
  img{
      animation-delay: (($duration * $i)) - $duration s;
    }
  }
}
like image 198
Tiago Coelho Avatar answered Oct 24 '22 02:10

Tiago Coelho