minh cù
minh cù

Reputation: 1

(css) Changing percent in @keyframe make Transform animation repeat

So i have a simple button with a shiny effect run through using ::after and transform.

.shiny {
  background-color: #000000;
  padding: 10px;
  color: white;
  border-radius: 5px;
  position: relative;
}

@keyframes sheen {
/*   make the sheen run forward for 1.5s then back for the last 0.5s */
      75% {
    transform: rotateZ(60deg) translate(1em, -9em);
  }  

}

.shiny::after {
  content: '';
  position: absolute;
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0));
  transform: rotateZ(60deg) translate(-5em, 7.5em);
}

.shiny:hover::after, .shiny:focus::after {
  animation: sheen 2s;
}
<button class="shiny">Shiny Button</button>

In original code, the percent in @keyframe was 100% and 'sheen' effect ran forward in exactly 2s. Here i set the percent to below 100% (75% for example), the effect will run forward for 75% of the animation-duration, then runs backward for the last 25%. Does that behavior have anything to do with 'transform' property? can anyone explain it to me

Upvotes: 0

Views: 318

Answers (1)

BOZ
BOZ

Reputation: 2020

As a matter of fact, the animation does not repeat itself. Animation begins-and-ends. It just emulates properties that give it a reference value when you not define what to do animation.

Here, you basically define that moment by giving concrete properties such as where it will be at the 75%th moment of 2s, what color it will be, what its opacity will be. But from 75.1% you haven't defined what to do until the animation is complete (100%).

If CSS Animations are not defined at any instant of the frames, they accept parent properties that refer to it.

.dummy {
  animation: dummy ... ... ...;
  opacity: .75;
}

@keyframes dummy {
   50% {
     opacity: .5;
   }
}

In the example above, the element will animate with an opacity of typically .75, .50 and .75 respectively.

If we didn't specify the property opacity: .75;, it would also animate the 1.0, .50 and 1.0 animation with default values.

You can imagine this for the opposite situation as well.

In other words, if I define where an element will be initially in the animation and this position is different from the values it actually references, the element will be animated by moving from the point I defined to the reference values.

Here is a simple example,

p {
  animation-duration: 3s;
  animation-name: slidein;
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 300%;
  }
}
<p>The Caterpillar and Alice looked at each other for some time in silence:
at last the Caterpillar took the hookah out of its mouth, and addressed
her in a languid, sleepy voice.</p>

Returning to the example in your question, it would suffice to define that it should exhibit the same behavior between 75% and 100%. Here is the example;

.shiny {
  background-color: #000000;
  padding: 10px;
  color: white;
  border-radius: 5px;
  position: relative;
}

@keyframes sheen {
/*   make the sheen run forward for 1.5s then back for the last 0.5s */
      75%, 100% {
    transform: rotateZ(60deg) translate(1em, -9em);
  }  

}

.shiny::after {
  content: '';
  position: absolute;
  top: -50%;
  right: -50%;
  bottom: -50%;
  left: -50%;
  background: linear-gradient(to bottom, rgba(229, 172, 142, 0), rgba(255,255,255,0.5) 50%, rgba(229, 172, 142, 0));
  transform: rotateZ(60deg) translate(-5em, 7.5em);
}

.shiny:hover::after, .shiny:focus::after {
  animation: sheen 2s;
}
<button class="shiny">Shiny Button</button>

Upvotes: 0

Related Questions