I am trying to create an animation loop on a full-screen image using keyframes for opacity and scale. Since I want this image to stay in view, I have placed it in a fixed container.
Everything behaves as expected in Chrome(69), Firefox(62), and Safari mobile 11. The problem only occurs in the older version(s?) of Safari mobile, observed in 10.3.3 on an iPad.
The project's navigation uses internal links to jump up and down the page. When the page jumps to an anchor, the animated image gets clipped (as in the top half or bottom half is missing) or it disappears altogether, and only renders properly with a new scroll event. This issue repeats anytime the internal links are used. When scrolling normally down the page, everything is fine.
I've tried replacing the keyframe animation with GSAP or by adding/removing classes in JS to animate, but nothing seems to help.
UPDATE: Workaround solution in the answer below
Here's the code in use:
.animation-wrapper {
position: fixed;
width: 100vw;
height: 100vh;
}
.animation-wrapper img {
width: 100%;
animation: pulse 8s ease-in-out infinite;
}
@keyframes pulse {
0% {
transform: scaleX(0.95);
}
50% {
transform: scaleX(1.05);
}
100% {
transform: scaleX(0.95);
}
}
body {
height: 4000px;
background-color: black;
}
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 20;
}
ul {
display: flex;
justify-content: space-around;
}
li > a {
color: white;
}
.anchor {
position: absolute;
top: 0;
}
section {
position: relative;
height: 1000px;
}
<nav>
<ul>
<li class="item"><a href="#home">HOME</a></li>
<li class="item"><a href="#projects">PROJECTS</a></li>
<li class="item"><a href="#about">ABOUT</a></li>
<li class="item"><a href="#contact">CONTACT</a></li>
</ul>
</nav>
<div class="animation-wrapper">
<img src="img1.jpg" alt="">
</div>
<section>
<a id="home" class="anchor"></a>
</section>
<section>
<a id="projects" class="anchor"></a>
</section>
<section>
<a id="about" class="anchor"></a>
</section>
<section>
<a id="contact" class="anchor"></a>
</section>
Does this issue sound at all familiar? Anybody know what is causing this behavior, and what I could possibly do as a workaround? It seems like a bug that was fixed in newer versions, but I would still like to get this project working in older Safari as well. Any insight is greatly appreciated.
I found a workaround solution for this issue.
While I don't fully understand the mechanics behind compositing layers and repaints, I did conclude that Safari 10 does not properly repaint the GPU-animated element when it's inside a fixed position container, and ONLY when using scroll-jumping mechanism like scrollTo() or internal links.
By forcing a repaint on the fixed container after every scroll jump, the animated image rendered properly without any clipping. For this purpose, I tried toggling display to none/block, but it restarted the animation each time. I found that toggling visibility on the fixed container allowed the child image to render properly without restarting the animation.
CSS
JS