6

I have a div with a background image and I'm trying to change its scale infinitely.

I changed the background-size property in the animation but as you can see, there is some noise or vibration when animating. How would I remove it?

.pre-loader {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  z-index: 9999;
  background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center no-repeat #fff;
  background-size: 50%;
  animation: loading 5s ease-in-out infinite;
}

@keyframes loading {
  0% {
    background-size: 50%
  }
  50% {
    background-size: 55%
  }
  100% {
    background-size: 50%
  }
}
<div class="pre-loader"></div>
Kareem Dabbeet
  • 3,838
  • 3
  • 16
  • 34

3 Answers3

8

Consider a scale transformation to have a better rendring:

.pre-loader {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  z-index: 9999;
  overflow:hidden;
}
.pre-loader:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center/50% auto no-repeat #fff;
  animation: loading 5s ease-in-out infinite;
}

@keyframes loading {
  50% {
    transform:scale(1.1);
  }
}
<div class="pre-loader"></div>

You are centering the background which means applying a background-position equal to 50%. The calculation of this value is related to the background-size so the position is changing slightly when the size is changing creating this bad effect:

If you consider a position using pixel values you will not see this effect:

.pre-loader {
  position: fixed;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  z-index: 9999;
  overflow:hidden;
}
.pre-loader:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') 50px 50px/50% auto no-repeat #fff;
  animation: loading 5s ease-in-out infinite;
}

@keyframes loading {
  50% {
    background-size:55%;
  }
}
<div class="pre-loader"></div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    But what would be the reason for the shaky effect, could you tell? – Anurag Srivastava Jul 25 '19 at 13:28
  • @AnuragSrivastava the calculation of background size is a bit complex because it also affect the background position. So when the size is changing the position is also changing slightly creating the shake effect (related to see the relation between size and position: https://stackoverflow.com/a/51734530/8620333 ) – Temani Afif Jul 25 '19 at 13:41
  • @AnuragSrivastava if you consider a static position (example; top left) you will not have any shake: https://jsfiddle.net/pqs6ocjy/ because the size doesn't affect the position in this case – Temani Afif Jul 25 '19 at 13:44
4

Use transform instead of background-size

.pre-loader {
 position: fixed;
 left: 0px;
 top: 0px;
 width: 100%;
 height: 100%;
 z-index: 9999;
 background: url('https://upload.wikimedia.org/wikipedia/commons/a/ab/Android_O_Preview_Logo.png') center no-repeat #fff;
 background-size: 50%;
 animation: loading 5s ease-in-out infinite;
}
@keyframes loading {
 50% { 
  transform: scale(1.2); 
 }
 100% { 
  transform: initial;
 }
}
    <div class="pre-loader"></div>
Félix
  • 388
  • 1
  • 9
0

There is nothing wrong with your code, the problems lays in the CSS. I think there is a performance issue in your animation with:

@keyframes loading { 
    0% { 
        background-size: 50% 
    }
    50% { 
        background-size: 55% 
    }
    100% { 
        background-size: 50% 
    }

The animation will relocate every single pixel from every image. So that will be a bit heavy for the browser to render I think.

Also your animation time with animation: loading 5s ease-in-out infinite; is a factor why its making noises. With the animation time of 5 seconds, it becomes clear that each pixel is reloaded.

If you change this time to 1s, you'll find that it runs smoother as the time between animations goes by faster.

But since the 5 seconds should persist, the simplest solution is to add the code snippets from @Félix or @TemaniAfif answer into your code which are really 2 great answers to your question.

41 72 6c
  • 1,600
  • 5
  • 19
  • 30