Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS animation delay in repeating

I've recently discovered how to "properly" use CSS animations (previously I dismissed them as not being able to make complex sequences like you could in JavaScript). So now I'm learning about them.

For this effect, I'm trying to have a gradient "flare" sweep across a progress bar-like element. Similar to the effect on native Windows Vista/7 progress bars.

@keyframes barshine {   from {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}   to {background-image:linear-gradient(120deg,rgba(255,255,255,0) 100%,rgba(255,255,255,0.25) 105%,rgba(255,255,255,0) 110%);} } .progbar {   animation: barshine 1s 4s linear infinite; } 

As you can see, I am trying to have a delay of 4 seconds, followed by the shine sweeping across in 1 second, repeated.

However, it seems that the animation-delay only applies to the first iteration, after which the shine just keeps sweeping across repeatedly.

I "resolved" this issue as follows:

@keyframes expbarshine {   from {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}   80% {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}   to {background-image:linear-gradient(120deg,rgba(255,255,255,0) 100%,rgba(255,255,255,0.25) 105%,rgba(255,255,255,0) 110%);} } .progbar {   animation: barshine 5s linear infinite; } 

from and 80% are exactly the same, resulting in a "delay" of 80% of the animation length.

This works, but for my next animation, I need the delay to be variable (constant for a particular element, but variable among elements that use the animation), while the animation itself stays exactly the same length.

With the above "solution", I would end up with a slower animation when all I want is a longer delay.

Is it possible to have the animation-delay apply to all iterations, rather than just the first?

like image 357
Niet the Dark Absol Avatar asked Dec 14 '12 23:12

Niet the Dark Absol


People also ask

How do I add a delay in an animated CSS?

The CSS animation-delay property has the following syntax: animation-delay: [time] | initial | inherit; As you can see, there are three possible values: time, initial, and inherit. The first option is [time], which is the number of seconds or milliseconds before the animation starts.

Can I use animation-delay?

The animation-delay CSS property specifies the amount of time to wait from applying the animation to an element before beginning to perform the animation. The animation can start later, immediately from its beginning, or immediately and partway through the animation.

How do you add a delay in CSS?

CSS Demo: transition-delay A value of 0s (or 0ms ) will begin the transition effect immediately. A positive value will delay the start of the transition effect for the given length of time. A negative value will begin the transition effect immediately, and partway through the effect.


2 Answers

I had a similar problem and used

@-webkit-keyframes pan {    0%, 10%       { -webkit-transform: translate3d( 0%, 0px, 0px); }    90%, 100%     { -webkit-transform: translate3d(-50%, 0px, 0px); } } 

Bit irritating that you have to fake your duration to account for 'delays' at either end.

like image 192
Sebastian Thomas Avatar answered Sep 20 '22 22:09

Sebastian Thomas


minitech is right in that animation-delay specifies the delay before the animation starts and NOT the delay in between iterations. The editors draft of the spec describes it well and there was a discussion of this feature you're describing here which suggesting this iteration delay feature.

While there may be a workaround in JS, you can fake this iteration delay for the progress bar flare using only CSS.

By declaring the flare div position:absolute and the parent div overflow: hidden, setting the 100% keyframe state greater than the width of the progress bar, and playing around with the cubic-bezier timing function and left offset values, you're able to emulate an ease-in-out or linear timing with a "delay".

It'd be interesting to write a less/scss mixin to calculate exactly the left offset and timing function to get this exact, but I don't have the time at the moment to fiddle with it. Would love to see something like that though!

Here's a demo I threw together to show this off. (I tried to emulate the windows 7 progress bar and fell a bit short, but it demonstrates what I'm talking about)

Demo: http://codepen.io/timothyasp/full/HlzGu

<!-- HTML --> <div class="bar">    <div class="progress">       <div class="flare"></div>    </div> </div>   /* CSS */  @keyframes progress {   from {     width: 0px;   }   to {     width: 600px;   } }  @keyframes barshine {   0% {     left: -100px;   }    100% {     left: 1000px;   } } .flare {   animation-name: barshine;   animation-duration: 3s;   animation-direction: normal;   animation-fill-mode: forwards;   animation-timing-function: cubic-bezier(.14, .75, .2, 1.01);   animation-iteration-count: infinite;   left: 0;   top: 0;   height: 40px;   width: 100px;   position: absolute;   background: -moz-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%, rgba(255,255,255,0) 87%); /* FF3.6+ */   background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(255,255,255,0.69)), color-stop(87%,rgba(255,255,255,0))); /* Chrome,Safari4+ */   background: -webkit-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* Chrome10+,Safari5.1+ */   background: -o-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* Opera 12+ */   background: -ms-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* IE10+ */   background: radial-gradient(ellipse at center,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* W3C */   filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b0ffffff', endColorstr='#00ffffff',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */   z-index: 10; } .progress {   animation-name: progress;   animation-duration: 10s;   animation-delay: 1s;   animation-timing-function: linear;   animation-iteration-count: infinite;   overflow: hidden;   position:relative;   z-index: 1;   height: 100%;   width: 100%;   border-right: 1px solid #0f9116;   background: #caf7ce; /* Old browsers */   background: -moz-linear-gradient(top, #caf7ce 0%, #caf7ce 18%, #3fe81e 45%, #2ab22a 96%); /* FF3.6+ */   background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#caf7ce), color-stop(18%,#caf7ce), color-stop(45%,#3fe81e), color-stop(96%,#2ab22a)); /* Chrome,Safari4+ */   background: -webkit-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* Chrome10+,Safari5.1+ */   background: -o-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* Opera 11.10+ */   background: -ms-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* IE10+ */   background: linear-gradient(to bottom, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* W3C */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#caf7ce', endColorstr='#2ab22a',GradientType=0 ); /* IE6-9 */ }  .progress:after {   content: "";   width: 100%;   height: 29px;   right: 0;   bottom: 0;   position: absolute;   z-index: 3;   background: -moz-linear-gradient(left, rgba(202,247,206,0) 0%, rgba(42,178,42,1) 100%); /* FF3.6+ */   background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(202,247,206,0)), color-stop(100%,rgba(42,178,42,1))); /* Chrome,Safari4+ */   background: -webkit-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* Chrome10+,Safari5.1+ */   background: -o-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* Opera 11.10+ */   background: -ms-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* IE10+ */   background: linear-gradient(to right, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* W3C */   filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00caf7ce', endColorstr='#2ab22a',GradientType=1 ); /* IE6-9 */ }  .bar {   margin-top: 30px;   height: 40px;   width: 600px;   position: relative;   border: 1px solid #777;   border-radius: 3px; } 
like image 22
tim Avatar answered Sep 21 '22 22:09

tim