10

I want to create a shine loading animation which will appear on multiple elements with different background colors.

Currently, I'm using background-image gradient and I'm animating the background-position using vw units, but it's not scalable, my elements will have different lengths.

Is there a way I can animate background-image with percentage units?

The animation created

body {
  background: black;
}

header {
  width: 100%;
  height: 50px;
  background-color: rebeccapurple;
  background-image: linear-gradient(
    to right,
    transparent 0%,
    rgba(255,255,255,0.3) 50%,
    transparent 100%
  );
  background-repeat: no-repeat;
  background-position: -100vw;
  animation: shine 2s infinite;
}

@keyframes shine {
  0% {
    background-position: -100vw;    
  }
  100% {
    background-position: 100vw;   
  }
}
<header></header>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Sartre
  • 145
  • 3
  • 8
  • 1
    Btw, this post is a good read when it comes to background image and percent: https://stackoverflow.com/questions/51731106/using-percentage-values-with-background-position-on-a-linear-gradient – Asons May 05 '19 at 07:34

1 Answers1

24

An idea is to make the size of the gradient to be 3 times bigger than the container and color the middle part of it then you slide it from left to right:

enter image description here

body {
  background: black;
}

.box {
  height: 50px;
  margin:5px;
  background: 
    linear-gradient(90deg,#0000 33%,rgba(255,255,255,0.3) 50%,#0000 66%)
    rebeccapurple;
  background-size:300% 100%;
  animation: shine 2s infinite;
}

@keyframes shine {
  0% {
    background-position: right;    
  }
  /*100% {
    background-position: left; it's the default value, no need to define it
  }*/
}
<div class="box"></div>

<div class="box" style="width:60%"></div>

<div class="box" style="width:40%"></div>

Another alternative for a different animation:

body {
  background: black;
}

.box {
  height: 50px;
  margin:5px;
  background: 
    repeating-linear-gradient(90deg,#0000 0,rgba(255,255,255,0.3) 25%,#0000 50%)
    rebeccapurple;
  background-size:200% 100%;
  animation: shine 1s infinite linear;
}

@keyframes shine {
  0% {
    background-position: right;    
  }
}
<div class="box"></div>

<div class="box" style="width:60%"></div>

<div class="box" style="width:40%"></div>

Related question: Using percentage values with background-position on a linear-gradient

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    You can create a separate class for background shine animation only and use `background-image` instead of `background` so that the background color will be inherited from the element itself and will not be overridden. `background-image: linear-gradient(315deg, #0000 33%, rgba(255, 255, 255, 0.3) 50%, #0000 66%);` – Shivam Sharma Jan 27 '22 at 08:27
  • Hi, thanks for the answer. Curious what is the difference between using ` linear-gradient(90deg, rebeccapurple 33%,rgba(255,255,255,0.3) 50%, rebeccapurple 66%)` instead of ` linear-gradient(90deg,#0000 33%,rgba(255,255,255,0.3) 50%,#0000 66%) rebeccapurple;`. Also, why does the rebeccapurple at the end apply in the example you give, #0000 seems like black, but why does the rebeccapurple apply to the background? Thank you! – James Feb 28 '22 at 15:01
  • @James #0000 is transparent not black (there are 4-digit not 3). I am keeping the main color outside of the gradient because the trick is to have a an extra layer above the main background. That background can be a simple color like here or something else. – Temani Afif Feb 28 '22 at 15:12
  • @TemaniAfif, So, by using #0000 (transparent) CSS background will use the color in the background-color behind linear-garident which is `rebeccapurple`? Anyways, Thank you!!!! – James Feb 28 '22 at 15:15
  • Hi, is it possible that I want to make the default background to be an linear garident as well? – Shawn Feb 28 '22 at 18:32
  • @Shawn https://jsfiddle.net/xLzmdfwa/ – Temani Afif Feb 28 '22 at 18:35