jaepage jaepage - 6 months ago 47
CSS Question

Animation of multiple background image positions via keyframes works in Chrome & Safari but not Firefox

The goal is to create an infinitely scrolling, two-layer parallax background. The effect works perfectly in Mac Chrome and Safari, but it stutters in Firefox. Any ideas why? Thanks!

<style>
body {
background-color: black;
}
#container {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
@-webkit-keyframes scroll {
100% {
background-position: 0 0;
}
}
@keyframes scroll {
100% {
background-position: 0 0;
}
}
.bg1 {
-webkit-animation: scroll 2.5s linear infinite;
animation: scroll 2.5s linear infinite;
background-image: url(path/to/image);
background-position: 0 -156px;
background-size: 128px 156px;
height: 100%;
opacity: 0.5;
position: fixed;
width: 100%;
}
.bg2 {
-webkit-animation: scroll 5s linear infinite;
animation: scroll 5s linear infinite;
background-image: url(path/to/image);
background-position: 0 -78px;
background-size: 64px 78px;
height: 100%;
opacity: 0.25;
position: fixed;
width: 100%;
}
</style>

<body>
<div id="container">
<div id="bg1" class="bg1"></div>
<div id="bg2" class="bg2"></div>
</div>
</body>

Answer

I was able to get around Firefox's engine not being to keep up with tandem animations of full-window divs of repeating backgrounds…by instead switching to two animated, patterned, full-window SVGs.

So rather than adding keyframe animations to divs in my CSS, I instead used the following markup in my HTML:

<svg id="parallax2" width="100%" height="200%" style="display: none;">
  <defs>
    <pattern id="pattern2" patternUnits="userSpaceOnUse" height="100" width="100">
      <image x="-40" y="-40" height="100" width="100" xlink:href="path/to/image"></image>
    </pattern>
  </defs>
  <rect width="100%" height="200%" fill="url(#pattern2)">
    <animateTransform
      attributeName="transform"
      type="translate"
      from="0 -50"
      to="0 50"
      dur="3750ms"
      repeatCount="indefinite"
    />
  </rect>
</svg>

<svg id="parallax1" width="100%" height="200%" style="display: none;">
  <defs>
    <pattern id="pattern1" patternUnits="userSpaceOnUse" height="200" width="200">
      <image x="-40" y="-40" height="200" width="200" xlink:href="path/to/image"></image>
    </pattern>
  </defs>
  <rect width="100%" height="200%" fill="url(#pattern1)">
    <animateTransform
      attributeName="transform"
      type="translate"
      from="0 -100"
      to="0 100"
      dur="3750ms"
      repeatCount="indefinite"
    />
  </rect>
</svg>