I have a skew transform applied to a div and I'm wanting to animate it on page load.
When I use the a keyframe animation, the skew is removed during the animation and then "pops" into place once the animation is complete.
How can I keep the skew applied to the div while the animation is in progress?
div {
-webkit-transform:skew(-197deg);
-moz-transform:skew(-197deg);
transform:skew(-197deg);
width: 200px;
margin-left: 40px;
animation: 1s ease-in-out 0s 1 slideInFromLeft;
}
#keyframes slideInFromLeft {
0% {
transform: translateX(-100%);
opacity: 0;
}
60% {
opacity: 0.5;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
<div>Hello, this is a skewed div that does not stay skewed when the animation is in progress.</div>
You need to add the skew to the animation or else the animation rule will overwrite it.
div {
-webkit-transform:skew(-197deg);
-moz-transform:skew(-197deg);
transform:skew(-197deg);
width: 200px;
margin-left: 40px;
animation: 1s ease-in-out 0s 1 slideInFromLeft;
}
#keyframes slideInFromLeft {
0% {
transform: skew(-197deg) translateX(-100%);
opacity: 0;
}
60% {
opacity: 0.5;
}
100% {
transform: skew(-197deg) translateX(0);
opacity: 1;
}
}
<div>Hello, this is a skewed div that does not stay skewed when the animation is in progress.</div>
How can I repeat a spinning animation x times before easing it out ?
For instance :
#spin-please {
background: green;
width: 50px;
height: 50px;
animation: spin 3s infinite ease-in-out;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
49% {
transform: rotate(359deg);
}
50% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
My animation right now is not very smooth at all (as you can see between the 1st and 2nd rotation), and there is an easing between the 2 rotations, which I want only at the start of the first of the rotation and at the end of the second (or the third if I choose to go with an additional rotation).
Easing in ==> rotation 1 ==> rotation 2 ==> easing out
Is this doable with CSS ?
Instead of repeating the animation infinite times, you can specify a number of repetitions like this:
animation: spin 3s 3 ease-in-out; /* 3secs, repeat 3 times */
See animation iteration count for more examples.
Also useful to see the animation short-hand docs to set all the properties at once (like your code does)
I am not sure what the desired outcome you are looking for but I modified the animation to display the spinning happening three times (with some reversal spin as well)
#spin-please {
background: green;
width: 50px;
height: 50px;
/* #keyframes duration | timing-function | delay |
iteration-count | direction | fill-mode | play-state | name
*/
animation: 1s 3 spin;
animation-timing-function: ease-in, linear, ease-out;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
The problem is totally not because your animation isn't smooth,
the problem with keyframes, according to this code
49% {
transform: rotate(359deg);
}
50% {
transform: rotate(0deg);
}
Your animation have to do 360deg rotation in very short time which is 1% ( between 49% - 50%) for any animation-timing-function value your animation is not smooth, Try this code :
#spin-please {
background: green;
width: 50px;
height: 50px;
animation: spin 3s ease infinite;
}
#keyframes spin {
0% {
animation-timing-function: ease-out;
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
animation-timing-function: ease-in;
transform: rotate(360deg);
}
}
<div id="spin-please">
</div>
Remember you can change your animation-timing-function in your keyframes. more details about animation-timing-function.
#spin-it {
background: green;
width: 50px;
height: 50px;
animation: spin 1.5s ease infinite;
}
#keyframes spin {
0% {
animation-timing-function: ease-out;
transform: rotate(0deg);
}
25% {transform: rotate(90deg);}
50% {
transform: rotate(180deg);
}
75% {transform: rotate(270deg);}
100% {
animation-timing-function: ease-in;
transform: rotate(360deg);
}
}
<div id="spin-it">
</div>
My version of MMJ's
It goes through 5 steps.
Ease in >>> Turn 1 side >>> Turn 1 side >>> Turn 1 side >>> Turn 1 side >>> Ease out
I am using WOW.js and animate.css, right now I am running my CSS to Infinite. I would like know how can I make my class run for 3 seconds stop and start again to infinite?
My html:
<img src="images/fork.png" class="fork wow rubberBand" >
My CSS class:
.fork {
position: absolute;
top: 38%;
left: 81%;
max-width: 110px;
-webkit-animation-iteration-count: infinite ;
-webkit-animation-delay: 5s;
}
The solution can be in JS or CSS3.
With pure CSS3 animations, one way to add a delay between every single iteration of the animation would be to modify the keyframes setting such that they produce the required delay.
In the below snippet, the following is what is being done:
The whole duration of the animation is 6 seconds. In order to have the delay, the whole duration should be the duration for which your animation actually runs + time delay. Here, the animation actually runs for 3s, we need a 3s delay and so the duration is set as 6 seconds.
For the first 50% of the animation (that is, 3 seconds), nothing happens and the element basically holds its position. This gives the appearance of the 3 second delay being applied
For the next 25% of the animation (that is, 1.5 seconds) the element moves down by 50px using transform: translateY(50px).
For the final 25% of the animation (that is, last 1.5 seconds) the element moves up by 50px using transform: translate(0px) (back to its original position).
The whole animation is repeated infinite number of times and each iteration will end up having a 3 second delay.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(0px);}
75% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
The animation-delay property introduces a delay only for the first iteration and hence it cannot be used to add delays between every iteration. Below is a sample snippet illustrating this.
div{
height: 100px;
width: 100px;
border: 1px solid;
animation: move 6s infinite forwards;
animation-delay: 3s;
}
#keyframes move{
0% { transform: translateY(0px);}
50% { transform: translateY(50px);}
100% { transform: translateY(0px);}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>Some content</div>
LIke this
html
<div class="halo halo-robford-animate"></div>
css
body{
background: black;
}
.halo{
width: 263px;
height: 77px;
background: url('http://i.imgur.com/3M05lmj.png');
}
.halo-robford-animate{
animation: leaves 0.3s ease-in-out 3s infinite alternate;
-webkit-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-moz-animation: leaves 0.3s ease-in-out 3s infinite alternate;
-o-animation: leaves 0.3s ease-in-out 3s infinite alternate;
}
#-webkit-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-moz-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#-o-keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
#keyframes leaves {
0% {
opacity: 1;
}
50% {
opacity: 0.5
}
100% {
opacity: 1;
}
}
jsfiddle
I try to make an animation that run every 3 seconds without JavaScript. My animation's duration is 1 second.
I'm only able to wait 3seconds the first occurence then it's a loop of 1s animation.
My code so far: https://jsfiddle.net/belut/aojp8ozn/32/
.face.back {
-webkit-animation: BackRotate 1s linear infinite;
-webkit-animation-delay: 3s;
animation: BackRotate 1s linear infinite;
animation-delay: 3s;
}
.face.front {
-webkit-animation: Rotate 1s linear infinite;
-webkit-animation-delay: 3s;
animation: Rotate 1s linear infinite;
animation-delay: 3s;
}
#-webkit-keyframes Rotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
from {-webkit-transform:rotateY(180deg);}
to {-webkit-transform:rotateY(540deg);}
}
#keyframes Rotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
#keyframes BackRotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
I know how to do it with javascript: https://jsfiddle.net/belut/fk3f47jL/1/
I tried this answer without success: Cycling CSS3 animation with a pause period?
Can you help me please?
EDIT
Thanks great answers i'm also able to make this scenario:
wait 2s, run 1s flip, wait 2s, run 1s back_flip, wait 2s.
#f1_container {
position: relative;
margin: 10px auto;
width: 90px;
height: 90px;
z-index: 1;
}
#f1_container {
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
}
img {
width: 90px;
height: 90px;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.face.back {
display: block;
transform: rotateY(180deg);
}
.face.back {
-webkit-animation: BackRotate 5s linear infinite;
}
.face.front {
-webkit-animation: Rotate 5s linear infinite;
}
#-webkit-keyframes Rotate {
0%,40% {-webkit-transform:rotateY(0deg);}
50%,90% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
0%,40% {-webkit-transform:rotateY(180deg);}
50%,90% {-webkit-transform:rotateY(360deg);}
100% {-webkit-transform:rotateY(540deg);}
}
It seems like the only way to achieve this is to extend the animation so that it lasts 4s instead of 1s. Then you could delay the animation by animating from 75% to 100% (rather than 0% to 100%).
In doing so, there is essentially an artificial delay in the animation itself. You just have to do the math to figure out how long this delay is in correlation with the total length of the animation itself.
Updated Example
.face.back {
display: block;
transform: rotateY(180deg);
}
.face.back {
-webkit-animation: BackRotate 4s linear infinite;
animation: BackRotate 4s linear infinite;
}
.face.front {
-webkit-animation: Rotate 4s linear infinite;
animation: Rotate 4s linear infinite;
}
#-webkit-keyframes Rotate {
75% {-webkit-transform:rotateY(0deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
75% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(540deg);}
}
#keyframes Rotate {
75% {-webkit-transform:rotateY(0deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#keyframes BackRotate {
75% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(540deg);}
}
I am not sure exactly when it was released, and it's not the most cross-browser approach (does not cover older browsers like I.E. 9) but you could use the animationPlayState style prop. Theres some documentation on this found here if you want to check it out.
animationPlayState=false
webkitAnimationPlayState=false
function pause() {
var animationElement = document.getElementById('animatedItem');
animationElement.style.animationPlayState='paused';
animationElement.style.webkitAnimationPlayState='paused';
}
As you can see this put's the items animation into a "paused"state, to put it back where it left the animation off at, you can set it to the "running" state that this prop accepts.
Here is a quick example I found when browsing Google.
I was able to do this, as #Josh mentioned, by extending the animation. For example, if you want your animation to last 0.5 seconds with a 3 second pause, you make the entire animation 3.5 seconds, and then use percentages to extend it. (0.5 seconds is about 14% of 3.5 seconds.)
In the code below, I created a DIV with transparent gradient that is the same width as the parent, and then animated it from left to right to give a shimmer effect.
.shimmer {
height: 100%;
width: 100%;
position: absolute;
top: 0px;
background-image: -moz-linear-gradient(160deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 25%, rgba(255,255,255,0.85) 60%, rgba(255,255,255,0) 100%); /* FF3.6+ */
background-image: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(25%,rgba(255,255,255,0)), color-stop(60%,rgba(255,255,255,0.85)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
background-image: -webkit-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
background-image: -o-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* Opera11.10+ */
background-image: -ms-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* IE10+ */
background-image: linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* W3C */
background-repeat: repeat-y;
background-size: 30% 100%;
left: -100%;
z-index: 101;
animation-name: shine;
animation-duration: 3.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
#keyframes shine {
0% { left: -100%; }
14% { left: 100%; }
100% { left: 100%; }
}
From 14% to 100%, the DIV doesn't move, but the animation continues for additional time, giving the effect of a pause.
You can add an ending state in the animation which will play like a delay. Check the example below, simple animation that runs for 4 sec but the last 3 sec is delayed.
body {
perspective: 500px;
}
/* clear background */
h2 {
text-align: center;
padding: 16px;
margin: 0;
}
/* crops animations that exceeds one line area */
.line {
width: 100%;
height: 4rem;
overflow: hidden;
padding: 0;
margin-bottom: 16px;
}
/* flipping class and key frames*/
.flipX {
animation: 4s anim-flipX ease infinite;
}
#keyframes anim-flipX {
0% {
opacity: 0;
transform: rotateX(9def);
}
20% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
60% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
100% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
}
<body>
<div class='line'>
<h2 class='flipX'>flip vertical</h2>
</div>
</body>
I have a bit of CSS3 animation which works perfectly in all the browser which support CSS3 except safari. Weird isn't it? Ok here's my code:
HTML
<div class="right">
<div class="key-arm"><img src="images/landing/key-arm.png" alt="arm" /></div>
</div>
CSS
.landing .board .right {
width: 291px;
height: 279px;
background: url('../images/landing/key-pnl.png');
bottom: 16px;
right: 250px;
position: absolute;
}
.landing .board .right .key-arm {
position: absolute;
left: 44px;
top: 18px;
width: 41px;
height: 120px;
}
/*=== Key Arm Animation ===*/
#-webkit-keyframes keyarm {
0% { -webkit-transform: rotate(0deg); }
5% { -webkit-transform: rotate(-14deg); }
10% { -webkit-transform: rotate(0deg); }
}
#-moz-keyframes keyarm {
0% { -moz-transform: rotate(0deg); }
5% { -moz-transform: rotate(-14deg); }
10% { -moz-transform: rotate(0deg); }
}
#-ms-keyframes keyarm {
0% { -ms-transform: rotate(0deg); }
5% { -ms-transform: rotate(-14deg); }
10% { -ms-transform: rotate(0deg); }
}
#-o-keyframes keyarm {
0% { -o-transform: rotate(0deg); }
5% { -o-transform: rotate(-14deg); }
10% { -o-transform: rotate(0deg); }
}
#keyframes keyarm{
0% { transform: rotate(0deg); }
5% { transform: rotate(-14deg); }
10% { transform: rotate(0deg); }
}
.right .key-arm{
-webkit-transform-origin: 12px 105px;
-moz-transform-origin: 12px 105px;
-ms-transform-origin: 12px 105px;
-o-transform-origin: 12px 105px;
transform-origin: 12px 105px;
-webkit-animation: keyarm 8s ease-in-out 0s infinite;
-moz-animation: keyarm 8s ease-in-out 4s infinite;
-ms-animation: keyarm 8s ease-in-out 4s infinite;
-o-animation: keyarm 8s ease-in-out 4s infinite;
animation: keyarm 8s ease-in-out 0s infinite;
}
Ok this doesn't work in Safari as I said, there's no movement whatsoever.
Also, still and only in Safari, the key-arm div shows only if you resize the screen! It's there in the DOM but for some reason it doesn't show up!
What am I doing wrong?
Thanks
Mauro
UPDATE: Ok from your answers I got that #keyframes is not supported on Safari 4. It's strange because on the same page I have an animation that works using #keyframes!
here's the CSS code:
.board .rays{
background: url("../images/landing/rays.gif") no-repeat 0 0 red;
height: 381px;
left: 251px;
opacity: 1;
top: 80px;
width: 408px;
position: absolute;
}
.board .bottle{
background: url("../images/landing/bottle.gif") no-repeat 0 0 lime;
bottom: 30px;
height: 405px;
left: 276px;
width: 357px;
z-index: 1;
position:absolute;
}
/*=== Rays Animation ===*/
#-webkit-keyframes rays{
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#-moz-keyframes rays{
0% { -moz-transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); }
}
.board .rays{
-webkit-animation: rays 40s linear 0s infinite;
-moz-animation: rays 40s linear 0s infinite;
animation: rays 40s linear 0s infinite;
}
And the html:
<div class="board">
<div class="rays"></div>
<div class="bottle"></div>
</div>
Try it yourself in jsFiddle (if you have Safari 4) and you'll see
Found the solution. In Safari when you use Keyframes you need to use the whole percentage:
this won't work:
#-webkit-keyframes keyarm {
0% { -webkit-transform: rotate(0deg); }
5% { -webkit-transform: rotate(-14deg); }
10% { -webkit-transform: rotate(0deg); }
}
this will:
#-webkit-keyframes keyarm {
0% { -webkit-transform: rotate(0deg); }
5% { -webkit-transform: rotate(-14deg); }
10% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(0deg); }
}
Don't know why but that's the way Safari works! :)
I was having troubles with CSS3 animation working in Safari 6, but not in Safari 4 (4.0.5).
It appears that the shorthand notation will not work in Safari 4.
So this won't work :
-webkit-animation: rays 40s linear forwards;
But this will work :
-webkit-animation-name: rays;
-webkit-animation-duration: 40s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: forwards;
In situations where you're trying to animate transform on something as soon as it's injected into the DOM, I've had to add a very brief delay, like this:
animation: rays 40s linear 0.01s infinite;
I struggled with an animation working in Safari 14 (14.1.2), but not in Safari 15, and thought I'd add my findings here.
This css is part of the scrolling text loop here.
#banner-loop {
white-space: nowrap;
animation: loop-anim 5s linear infinite;
}
#keyframes loop-anim {
0% { margin-left: 0; }
100% { margin-left: -50%; }
}
I noticed that the animation "played", but didn't animate.
I tried the solutions from the other answers here, but nothing worked (including having the -webkit prefix). In the end the problem was solved by changing the start keyframe value to 0% instead of 0.
It looks like Safari can't handle the unit-less 0 shorthand in this case.
Try force quitting Safari and/or rebooting your phone (assuming you're on a phone).
Just had animations fail in Safari 15 for no apparent reason - very simple ones such as opacity and simple keyframes.
I noticed my phone was doing that thing where the white homescreen indicator gets permanently stuck on the long side of the phone even when holding it vertically. A reboot is usually needed to fix that.
Turns out rebooting also fixed the animations in Safari.
Another thing to remember with Safari is that low battery mode can affect animations and make them less smooth (and prevent muted autoplay videos from auto playing).
#-webkit-keyframes { <- let this symbol to the same line
} - >
This works on iphone 3 ios 6.1.6
with -webkit- prefix on transform and animation