Search code examples
cssfirefoxcss-animationsbackground-imagebackground-position

background-position animation isn't running smooth in Firefox compared to Chrome and Edge


I'm trying to create a smooth animation using background-position to simulate the background image moving slowly. While the animation works as expected in Chrome and Edge, in Firefox, the animation isn't running smooth; the background position of the image moves in small jumps.

If you open this link with Firefox and with Chrome or Edge, you can see the difference.

My html code:

<!DOCTYPE html>
<html>
  <head>
    <title>My Website</title>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <div class="img-background-horizontal"></div>
  </body>
</html>

The css code:

body {
  padding: 0;
  margin: 0;
}

.img-background-horizontal {
  background-image: url("https://cdn.pixabay.com/photo/2020/12/18/15/29/mountains-5842346_1280.jpg");
  background-size: 105vw auto;
  background-position: 0% 0%;
  height: 100vh;
  width: 100vw;
  animation: horizontalMove 50s infinite;
  animation-timing-function: ease;
}

@keyframes horizontalMove {
  0% {
    background-position: 0% 0%;
  }
  50% {
    background-position: 100% 20%;
  }
  100% {
    background-position: 0% 0%;
  }
}

I attempted to resolve the issue by changing the animation-timing-function to, for example, cubic-bezier, but the problem persists. I suspect that the issue arises in Firefox when the animation runs at a very slow pace. When I reduce the animation-duration to a few seconds, the animation runs faster and appears smooth. However, adjusting this parameter is not a viable solution for me.

What steps can I take to resolve this?


Solution

  • Firefox seems to be able to smoothly transition an element.

    This snippet gives an example with the backgrouund on the before pseudo element which is made bigger than actual div and is the thing that is animated.

    Note: background-size is set to cover and centered so it looks OK on any viewport size.

    You will want to alter the % translates to suit your requirements.

    body {
      padding: 0;
      margin: 0;
    }
    
    .img-background-horizontal {
      height: 100vh;
      width: 100vw;
      position: relative;
      overflow: hidden;
    }
    
    .img-background-horizontal::before {
      content: '';
      background-image: url("https://cdn.pixabay.com/photo/2020/12/18/15/29/mountains-5842346_1280.jpg");
      background-position: 0% 0%;
      height: 110vh;
      width: 110vw;
      animation: horizontalMove 50s infinite;
      animation-timing-function: ease;
      position: absolute;
      top: -2.5vh;
      left: -2.5vw;
      background-size: cover;
      background-position: center center;
      overflow: hidden;
    }
    
    @keyframes horizontalMove {
      0%,
      100% {
        transform: translate(0, 0)
      }
      50% {
        transform: translate(-5%, 2%);
      }
    }
    <div class="img-background-horizontal"></div>