Search code examples
cssinternet-explorercss-animationskeyframebackground-position

Flickering when using keyframes + background position on sprite sheet in IE11


So I have a sprite sheet containing 16 frames of a walking animation and I intent to animate it with keyframes by changing the background position using:

animation: abc 0.55s infinite steps(1);


    @keyframes abc {
        0%  {background-position(-2250vh,-10vh);}
        6.67%   {background-position(-2100vh,-10vh);}
        13.33%  {background-position(-1950vh,-10vh);}
        ...
        100%    {background-position(0,-10vh);}
    }

It works fine in chrome and firefox but in IE, at the end of the animation, it disappears briefly before looping again. Creating a flickering effect

When I turned the animations off and manually test each position using the console, each frame is displayed correctly, so this is not due to incorrect positioning.


Solution

  • Don't animate background-position. This does cause performance issues. Instead, use img and let it be as tall as it needs. Wrap it in a div like so...

    <div class="wrapper">
      <img class="image" src='some-tall-image.png'/>
    </div>
    

    Adjust the wrapper height to be as tall as a desired frame (From your keyframes i asumed it to be 150px). And set overflow:hidden on .wrapper

    .wrapper {
      height:150px;
      overflow:hidden;
    }
    

    This should display only what you want to see. A single frame of your sprite-sheet. And to animate use transform:translateY() on the img

    @keyframes abc {
        0%  {transform:translateY(-2250vh);}
        6.67%   {transform:translateY(-2100vh);}
        13.33%  {transform:translateY(-1950vh);}
        100%    {transform:translateY(0vh);}
    }
    
    .image {
      animation: abc ...;
    }
    

    EXAMPLE. Check it out...

    BY using steps(8) I need only set the 100% keyframe of the animation. The rest gets filled in... MAGIC!... Also created a JSFiddle for ya

    I borrowed the sprite sheet. Props to the creator (whose url can be seen on the code). Image is 960px wide. So in my case I used translateX instead of translateY.

    @keyframes walking {
      100% { 
        transform:translateX(-960px);
       }
    }
    
    .wrapper {
      overflow:hidden;
      width:120px;
    }
    
    .image {
      animation:walking 500ms steps(8) infinite;
    }
    <div class="wrapper">
      <img class= "image" src="https://www.adamkhoury.com/demo/sprite_sheets/adam.png">
    </div>