1

I built a semi-transparent sprite png which can be found at https://www.srf.ch/static/srf-data/test_sprite.png It is a 17280px high and 910px wide png (30 * 576 = 17280) - everything seems correct.

I now want to loop through each frame (it should be a map of slightly moving points) with CSS3 keyframes using background-position.

I adapted an example from https://builtvisible.com/3-logical-alternatives-to-animated-gifs/ (see http://codepen.io/tombennet/pen/oxmaLd)

I can reproduce that example, when I try to adapt it to my needs (i.e. my sprite), I get this: http://codepen.io/anon/pen/rmwwMG

Now: On IE11, Windows 7, this thing is jumping very slightly up and down. In FF or Chrome it is displaying correctly.

What startles me is that the Ninja guy from the initial example doesn't jump, he seems to work fine. I wonder what the difference in my sprite/css is.

grssnbchr
  • 2,877
  • 7
  • 37
  • 71

1 Answers1

1

On IE11, Windows 7, this thing is jumping very slightly up and down. In FF or Chrome it is displaying correctly.

My guess is that the issue is caused by the way different browsers handle the rounding of floating point numbers. IE11 (as well as Edge) truncates after the second decimal place which makes the positioning sometimes imprecise. There have been lot of complaints about this behaviour as for example the building of a layout grid (columns) with percentage values requires some additional hacks to add the columns' width to 100%.

In Firefox (53) and Chrome (57) the number is rounded to at least the fourth decimal. That makes a visible difference in your example. If we have 29 steps, each step moves the background-image by 3.448...%, so after 6 steps the value should be at 20.6896...%. I took this specific step as here we get the biggest difference between the actual value and the visible value shown in IE11 (20.68%). This results in an inaccuracy of ~1.67px. On average we have an inaccuracy of 0.86px in this example.

The reason why it does not flicker in the ninja example is that the inaccuracy is lower (due to a smaller image height of 752px compared to your 17280px; note that the image's height gets multiplied by the percentage value so that a higher pixel value has a greater impact). The maximum difference between the actual value and the rendered value is only 0.0752px and on average we only have an inaccuracy of 0.0376px in the ninja example.

How to solve the issue

It's really as simple as not to rely on floating point numbers in this scenario. We move the background-image by 576px for 30 steps:

.test {
  width: 910px;
  height: 576px;
  background:  url('https://i.stack.imgur.com/Tsw6G.png') no-repeat 0 0%;
  animation: sprite 1s steps(30) infinite;
}

@keyframes sprite {
  from { background-position: 0 0px; }
  to { background-position: 0 -17280px; }
}
<div class="test"></div>
Marvin
  • 9,164
  • 3
  • 26
  • 44
  • Absolutely great answer - it makes things clear and presents a working solution, thanks a lot. I actually experimented with setting pixel values but I still used 29 steps (instead of 30) and I wrongly specified `background-position: 0 17280px` instead of the negative number. If I assume correctly one uses negative values because that's how the pixel coordinate system works? – grssnbchr May 04 '17 at 09:43
  • 1
    I am glad that you like it :) I enjoy debugging and answering these kind of edge cases. Regarding the question with the negative value: if you want the image to move to the top you have to *pull it up*. [I've quickly created a fiddle](https://jsfiddle.net/sgv5a6cm/) for demonstrating how positioning works (just imagine that the background placeholder is one frame of your image). – Marvin May 04 '17 at 10:25
  • I now tried to adapt an example from https://www.sitepoint.com/responsive-sprite-animations-imagemagick-greensock/ in order to make it responsive. There (I guess) I had to use percentages. Now the image even jumps in Chrome et al., depending on the window width: http://codepen.io/anon/pen/QvQWJP. Interestingly, at 910px it works great (probably because that's the original size). The article also talks about EMs and setting the base font size, maybe that would be a possibility (instead of percentages?). Quick help would be greatly appreciated! – grssnbchr May 09 '17 at 18:09
  • I tried several things but couldn't figure out what's the reason for this behaviour here, sorry :( – Marvin May 09 '17 at 20:04