Search code examples
androidcssbackgroundbackground-position

CSS3 background-position animation lags on mobile devices


I'm trying to create a scrolling effect for a background using CSS3 animations, such as:

body {
  background: url("bg.jpg") repeat-y 0 0;
  animation: animatedBackground 50s linear infinite;
}

@keyframes animatedBackground {
  from { background-position: 0 0; }
  to { background-position: 0 100%; }
}

(JSFiddle)

This works great, except that it's very laggy on mobile devices (e.g. Android Chrome 43.0)). I've tried various hacks that are suppose to force the browser to use the GPU, which sadly didn't help.

One solution is to use translateY and duplicate the image, like shown here. That doesn't feel very good however, since the image is pretty big to start with. It does run smooth, though.

I'm looking for alternate solutions on how to make this run smooth.


Solution

  • Inspired by the link in the OP, I found a way to achieve this without having multiple references to the same image. It does, however, require you to know the image's height.

    The general idea is to have a relative wrapper which hides all overflow, and force the image to be 200% its height, and make it repeat and finally animate the y-axis -100%. Example:

    #parallax-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    
    #parallax-background {
      position: relative;
      width: 100%;
      height: @parallax-image-height * 2;
      background: url("/bundles/sunnerbergsimilarseries/images/tv-show-wall.jpg") repeat 0 0;
      animation: animatedBackground 50s linear infinite;
      transform: translate3d(0, 0, 0);
    }
    
    @keyframes animatedBackground {
      0% { transform: translateY(0) }
      100% { transform: translateY(-@parallax-image-height) }
    }
    

    (JSFiddle)

    The above runs as smooth on a 2015 Android-phone as on a computer with a dedicated graphics card.