I've made a pie timer animation using only HTML/CSS. You can see it here:
https://jsfiddle.net/yisusans/why2wy5q/
.timer-container {
background: -webkit-linear-gradient(left, #677291 50%, #D8DAE5 50%);
border-radius: 100%;
height: 30px;
position: relative;
top: 5px;
left: 9px;
width: 30px;
-webkit-animation: time 20s linear 1;
animation: time 20s linear 1;
-webkit-transition-timing-function: ease-in;
transition-timing-function: ease-in;
-webkit-transition-duration: 1s;
transition-duration: 1s;
-moz-transform: translateZ(1) scale(1.0, 1.0);
-ms-transform: translateZ(1) scale(1.0, 1.0);
-o-transform: translateZ(1) scale(1.0, 1.0);
-webkit-transform: translateZ(1) scale(1.0, 1.0);
transform: translateZ(1) scale(1.0, 1.0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.timer {
border-radius: 100% 0 0 100% / 50% 0 0 50%;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 50%;
-webkit-animation: mask 20s linear 1;
-webkit-transform-origin: 100% 50%;
-webkit-transition-timing-function: ease-in;
-webkit-transition-duration: 1s;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#-webkit-keyframes time {
100% {
-webkit-transform: rotate(360deg);
}
}
#-webkit-keyframes mask {
0% {
background: #D8DAE5;
-webkit-transform: rotate(0deg);
}
50% {
background: #D8DAE5;
-webkit-transform: rotate(-180deg);
}
50.01% {
background: #677291;
-webkit-transform: rotate(0deg);
}
100% {
background: #677291;
-webkit-transform: rotate(-180deg);
}
}
#keyframes time {
100% {
transform: rotate(360deg);
}
}
#keyframes mask {
0% {
background: #D8DAE5;
transform: rotate(0deg);
}
50% {
background: #D8DAE5;
transform: rotate(-180deg);
}
50.01% {
background: #677291;
transform: rotate(0deg);
}
100% {
background: #677291;
transform: rotate(-180deg);
}
}
<div class='timer-container'>
<div class='timer'></div>
</div>
It works but it's a bit shaky. Any tips to smooth out the animation would be amazing.
Thanks!
It's running very smoothly on my MacBook Pro in Safari, Chrome and Firefox, but CSS animations are subject to performance differences between devices and browsers. You might just be seeing the limitations of your device.
It's also likely to run more smoothly outside of jsfiddle.
I came across this post:
Improving CSS3 transition performance
It's been pretty informative in relation to animation performance. But I'd love to see if anyone else has any other insights.
firstly,
good job...
secondly,
It seems I am 4 years late for this answer. but, here goes...
Like #dave suggested in the above post... I also failed to recreate the shakiness issue you have with the animation. (even increasing the height and width property of the .timer-container selector and taking a closer look) It's running pretty smooth. And there seems to be nothing wrong with the code snippet you have provided.
But I will leave this answer for people who want a quick fix for common CSS animation shakiness that they might experience.
set
backface-visibility: hidden;
on the element, you are animating.
and only change opacity and transform property when animating.
Browsers are optimized for animating these properties and will ensure that you minimize any performance overhead.
Pretty much any animation you want can be achieved using transforms.
Related
I am trying to make an Oscillatory animation using css as shown below:
Here's how I have created my animation:
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(-180deg);
}
50% {
transform: rotate(-90deg);
}
75% {
transform: rotate(90deg);
}
100% {
transform: rotate(180deg);
}
}
Here is my class: (Using sccs)
.logo {
height: 5rem;
transition: all 0.3s ease;
&box {
position: absolute;
top: 4rem;
left: 4rem;
}
&:hover {
animation-name: rotateFeather;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
}
Here I am facing this problem: When it reaches 180deg at 100% it abruptly resets to 0 which I want to make smooth.
How is it possible to do the same?
To ensure smooth transition, We need to make sure that transformation at 0 and 100% must match with the original state:
#keyframes rotateFeather {
0% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
20% {
transform: rotate(-30deg); //-60
transform-origin: bottom;
}
40% {
transform: rotate(0deg); //-30
transform-origin: bottom;
}
60% {
transform: rotate(30deg); // 0
transform-origin: bottom;
}
80% {
transform: rotate(60deg); //30
transform-origin: bottom;
}
100% {
transform: rotate(0deg); //30
transform-origin: bottom;
}
}
This helped me to solve my issue. I am not sure, if I need to add transform-origin in every stage, if someone can elaborate better on that, that would be helpful.
Here's a simplified version of your latest animation code (with a Codepen to see it in action):
#keyframes rotateFeather {
0% {
transform: rotate(0deg);
}
20% {
transform: rotate(-30deg);
}
80% {
transform: rotate(60deg);
}
100% {
transform: rotate(0deg);
}
}
.logo {
transform-origin: bottom;
&:hover {
animation: rotateFeather 1s linear infinite;
}
}
Some points about the above tweaks:
You don't need transform-origin at every keyframe. You can set it globally.
You can roll all of your animation properties into a single shorthand rule.
You can skip keyframes that are mathematically interpolating where the animation would be going anyway (notice I omitted 40% and 60% above and it looks the same).
You don't need any transition rules on elements that you are animating with keyframes. Unless you're using it for something else, but you want to be careful to avoid attempting to animate the same property on the same element with both animation and transition simultaneously, as it will break the animation in question.
I wanna make a drop animation when the page loads similar to a working example I've seen at someone else but mine doesn't. The image doesn't drop at all, does not transition from 0 opacity to 1 opacity. It just suddenly appears after the given duration. Help me, please.
.cover img{
height: 60vh;
filter: drop-shadow(1px 5px 3px black);
position: relative;
left: 60px;
animation: drop 1.5s ease;
}
#keyframes drop{
0% {
opacity: 0%;
transform: translateY(-80px);
}
100% {
opacity: 1%;
transform: translateY(0px);
}
}
What I think you've done wrong is used a percentage in the opacity. You just need the number.
#keyframes drop {
0% {
opacity: 0;
transform: translateY(-80px);
}
100% {
opacity: 1;
transform: translateY(0px);
}
}
Does this help?
Animation i've created works fine on Chrome and Firefox, but is pixelated on Safari (version 10.1.1) and IE11.
Tried using translateZ() / translate3d() so the gpu can render the animations but nothing happened.
I've avoided using top, left props. Had an idea of using the will-change prop but it doesn't take animation as a value.
Removing the border radius would fix the rendering issue.
Can someone explain the cause of this and is there a solution to fix this issue?
https://codepen.io/imrdev/pen/awBZOW
html ->
<div class="dot"></div>
css - >
/* KEYFRAME ANIMATION */
#keyframes ease {
0% {
transform: scale(0) rotate(0);
}
50% {
transform: scale(4)
rotate(.01deg);
}
100% {
transform: scale(0) rotate(0);
}
}
#keyframes ease2 {
0% {
transform: scale(0) rotate(0);
}
50% {
transform: scale(6)
rotate(.01deg);
}
100% {
transform: scale(0) rotate(0);
}
}
.dot {
$scale-duration: 15s;
background-color: black;
position: relative;
width: 7px;
height: 7px;
border-radius: 50%;
&::before,
&::after {
content: "";
background: red;
width: 7px;
height: 7px;
border-radius: inherit;
opacity:.3;
position: absolute;
transform: translate(0px, 0px);
}
&::before {
animation: ease 5s ease-in-out infinite;
}
&::after {
animation: ease2 5s ease-in-out infinite both $scale-duration/15;
}
}
Thanks :-)
I have not enough reputation so i can't comment yet, so sorry if this doesn't qualify as a proper answer, but have you tried changing the size to something bigger than 7px and use eg scale(1) instead of scale(4)?
if you need to scale the width and height up by 4 or 6, why not just double the original size and scale up by 2 ?
I wouldn't be surprise if safari doesn't really scale the size up, but kinda like "zooms in" and since the original size is just 7 x 7 px it gets pixelated when "zoomed in"
and regarding to the will-change: you wouldn't use "animation" but "transform"
I have a CSS3 Animation for an indeterminate progress bar. In the animation I have a gradient oscillating back and forth along the progress bar. I would like to flip the image of gradient horizonally as it travels back to the left side of the progress bar. Basically the gradient always fades out the opposite direction the image is moving. Unfortunately I can't figure out a way for the image to flip horizontally BEFORE it starts moving back towards the left and am getting some odd transformations of the image as it flips.
I have created a JSFiddle to show how it looks right now.
http://jsfiddle.net/MtWzL/
Here is the CSS I'm currently using for the animation:
#-webkit-keyframes loader {
0% {
-webkit-transform: scaleX(1);
-webkit-transform: translateX(-100px);
-webkit-transform-origin:left;
}
50% {
-webkit-transform: translateX(300px);
}
100% {
-webkit-transform: translateX(-100px);
-webkit-transform: scaleX(-1);
}
}
#keyframes loader {
0% {
transform: scaleX(1);
transform: translateX(-100px);
transform-origin:left;
}
50% {
transform: translateX(300px);
}
100% {
transform: translateX(-100px);
transform: scaleX(-1);
}
}
.slider
{
animation: loader 2.5s infinite linear;
-webkit-animation: loader 2.5s infinite linear; /* Safari and Chrome */
background: url('http://s23.postimg.org/mglkwgxuv/indeterminate_bg.png') no-repeat;
border-radius: 10px;
height: 10px;
position: relative;
width: 100px;
z-index: 999;
opacity: .6;
}
.container {
background: -webkit-linear-gradient(#00c3ff,#0071bc);
background: linear-gradient(#00c3ff,#0071bc);
border-radius: 3px;
height: 10px;
overflow: hidden;
width: 300px;
}
.background {
background: rgba(0,0,0,0.7);
border-radius: 3px;
display: inline-block;
padding: 10px;
}
There are 2 issues that need to be fixed
first of all, this
-webkit-transform: scaleX(1);
-webkit-transform: translateX(-100px);
won't work as you expect; the second property over-rides the first one, as you can not set 2 different values for a property in separate lines.
the correct syntax would be
-webkit-transform: translateX(-100px) scaleX(1);
And second, if you want a sudden change in some value, you need to set it from a keyframe to another keyframe close enough to the first one.
So, the solution would be
#-webkit-keyframes loader {
0% { -webkit-transform: translateX(-100px) scaleX(1); }
50% { -webkit-transform: translateX(300px) scaleX(1); }
51% { -webkit-transform: translateX(300px) scaleX(-1); }
100% { -webkit-transform: translateX(-100px) scaleX(-1); }
}
corrected fiddle
I have corrected only the webkit transforms, but the same concept applies to the rest.
I was watching for your problem since you put it here, but I guess its some kind of bug we won't solve or maybe I just dont understand why it is working like that.
Since I had no clue how to solve it I manage to do example for you with alternative solution
EXAMPLE
As you can see I modified your jsfiddle, simple words, created another slide loader .sliderBack that goes backwards. Hope it will helps you somehow. Peace :)
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