CSS3 animation iteration count 1 vs infinite chrome compatibility - css

Ok. I tried to search for this question. and it's very simple. I have a css swing animation working good in firefox but not in chrome. Of course, I added the webkit prefix. but still no luck. I changed the iteration count to infinite and finally it is working, but no I don't want it to run infinitely. Is this really a bug? does anybody find a solution? here's the link to the code I made in jsfiddle .. http://jsfiddle.net/7t1uvyup/2/ and here's the actual code.
.x{
height:50px;
width:50px;
background:#000;
position:fixed;
}
.x:hover
{
-webkit-animation: swing 1s ease;
animation: swing 1s ease;
/* change webkit iteration count to infinite and it will work on chrome but of course with infinite animation */
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
#-webkit-keyframes swing
{
15%
{
-webkit-transform: translateX(5px);
transform: translateX(5px);
}
30%
{
-webkit-transform: translateX(-5px);
transform: translateX(-5px);
}
50%
{
-webkit-transform: translateX(3px);
transform: translateX(3px);
}
65%
{
-webkit-transform: translateX(-3px);
transform: translateX(-3px);
}
80%
{
-webkit-transform: translateX(2px);
transform: translateX(2px);
}
100%
{
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes swing
{
15%
{
-webkit-transform: translateX(5px);
transform: translateX(5px);
}
30%
{
-webkit-transform: translateX(-5px);
transform: translateX(-5px);
}
50%
{
-webkit-transform: translateX(3px);
transform: translateX(3px);
}
65%
{
-webkit-transform: translateX(-3px);
transform: translateX(-3px);
}
80%
{
-webkit-transform: translateX(2px);
transform: translateX(2px);
}
100%
{
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
<div class="x"></div>

I did some research.. CSS is Hardware-Accelerated..
So this is not just a weird random bug.

I ran into this problem just now. To me it seems that the animation takes place in very short period of time and many times it is not noticable to human eyes; i.e. Chrome does not respect animation duration parameter when webkit-animation-iteration-count is not infinite.
To me it doesn't seem to be a random bug. It is reliably reproducible.
Try visiting http://www.w3schools.com/css/css3_animations.asp with different browsers. Chrome shows the worst performance; CSS3 animation box does not animate; it just stays.

Related

Oscilatory Animation CSS: How to avoid abrupt transition from 100% to 0%?

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.

Any downside on showing the same CSS Animation multiple times on a webpage?

I managed to put the same bootstrap spinner animation behind my lazyloaded images through CSS position: relative and z-index on my masonry grid. After images are loaded the loaded images are displayed above (z-index) the animation and i do not remove them. They just run behind the images.
Any downside on doing this with regards to webpage & browser rendering and so on performance, because my site uses infinite scroll and a lot of images are coming into view?
For the mentioned animation I'm using the following:
.lodi:before,
.fa-pulse {
-webkit-animation: fa-spin 1s infinite steps(8);
animation: fa-spin 1s infinite steps(8)
}
#-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg)
}
}
#keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg)
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg)
}
}
.fa-rotate-90 {
filter: progid: DXImageTransform.Microsoft.BasicImage(rotation=1);
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}

Waving flag effect CSS3 performance issues

I have a set of boxes where each box has an animation:
#keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(0); }
100% { transform: scale(1); }
}
In order to create a waving flag effect, I use the animation-delay CSS property:
.pulsate1 {
-webkit-animation-delay: 2s;
}
.pulsate2 {
-webkit-animation-delay: 2.05s;
}
/* And so on up to pulsate20 */
These pulsateN classes are wrapped around each row of boxes.
There is some occasional flickering using this method, as seen in this fiddle. Is there another better solution?
The flickering occurs because CSS doesn't know what to do with scale of 0. Change it to something low like 0.001 and enjoy your smoothly-waving flag :)
#keyframes pulse {
0% { transform: scale(1) translateZ(0); }
50% { transform: scale(0.001) translateZ(0) }
100% { transform: scale(1) translateZ(0) }
}
(As mentioned by skyline You can add translateZ(0) to take advantage of the GPU)
scale() is a 2D transformation style. Try adding translateZ(0) or translate3d(0,0,0) to the animation. This will trick the browser into thinking it's doing 3D transformations and will offload the work to the GPU if available. I'm not seeing any flickering on Chrome 49.
#keyframes pulse {
0% { transform: scale(1) translateZ(0); }
50% { transform: scale(0) translateZ(0); }
100% { transform: scale(1) translateZ(0); }
}
Here's an article explaining the performance benefits of translate3d: https://aerotwist.com/blog/on-translate3d-and-layer-creation-hacks/

Grow circular image using keyframes and CSS

I'm trying to grow a circular image on hover, but can't get this code to work.
I can get the circle to grow using the CSS transform but it grows immediately and is a bit ugly. Ideally I'd want there to be a 2-3000ms delay with linear growth both on hover and mouse out.
I know I can do this with JS/D3 but need to do it with CSS if possible.
Have tried
.wpb_single_image .vc_single_image-wrapper.vc_box_circle:hover
{
animation: mymove 3s normal;
}
#-webkit-keyframes mymove {
0%
{
width:250px;}
25%
{
width:260px;}
75%
{
width:270px;}
100%
{
width:280px;
}
}
and
.wpb_single_image .vc_single_image-wrapper.vc_box_circle:hover
{
animation: mymove 3s normal;
}
#-webkit-keyframes mymove {
0%
{
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);}
}
25%
{
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);}
75%
{
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);}
100%
{
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
But neither are working.
Is there a better way to do this?
I've created a pen based on your code
Using transform: scale is a better method since it increases both width and height.
The key thing you missed out on for creating a smooth animation is the transition attribute, this needs to be applied to the element in it's normal state not it's :hover state.
I've added this transition styling:
transition: 3s ease-in-out;
Note that it's the same length as your animation timing. ease-in-out is a standard easing function, if you'd like to get more in-depth try playing around with cubic-bezier
Animation delay can be added easily with this attribute:
animation-delay:2s
Another thing which makes keyframe animations smoother is having the 0% and 100% stylings the same, so in this example the circle returns to the original scale by the time it reaches 100% which creates a nice, smooth, repeatable animation.
I've also created an alternative animation which looks even smoother, this is done by simply setting scale for the 0% and 100% points in the animation:
0%{transform: scale(1)}
100%{transform: scale(2)}
Another thing you can do is change your animation loop setting from normal to infinite alternate, checkout my second example this is using infinite alternate which makes the circle grow and shrink with no sudden snaps.
You can delay the start of an animation with animation-delay
Such as
.delay {
animation-delay:2s
}
Reference # MDN
Demo showing the difference below
.circle {
border-radius: 50%;
display: block;
}
.circle:hover {
animation: mymove 3s normal;
}
.delay:hover {
animation-delay: 2s
}
#-webkit-keyframes mymove {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
}
25% {
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);
}
75% {
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);
}
100% {
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
#-webkit-keyframes mymove {
0% {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
25% {
-webkit-transform: scale(1.033);
-ms-transform: scale(1.033);
transform: scale(1.033);
}
75% {
-webkit-transform: scale(1.066);
-ms-transform: scale(1.066);
transform: scale(1.066);
}
100% {
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
}
<div>
<img src="http://lorempixel.com/output/abstract-q-c-100-100-4.jpg" alt="" class="circle" />
</div>
<div>
<img src="http://lorempixel.com/output/abstract-q-c-100-100-4.jpg" alt="" class="circle delay" />
</div>
You can delay the start of the transition by using the transition-delay property.
div {
-webkit-transition-delay: 2s; /* Safari */
transition-delay: 2s;
}
W3Schools

How to make CSS color transition time correctly with transform perspective?

So I have this cute little spinner made to signify when something is loading. The perspective changes and the background color are supposed to change at the same time. I am having trouble getting the Transform and Transition timings to line up so that you don't see the color change, it needs to be already changed when the square flips so that it is a smooth transition.
Link to JS Fiddle
HTML
<div class="spinner"></div>
CSS
.spinner {
width: 20px;
height: 20px;
-webkit-animation: rotateplane 1.2s infinite ease-in-out;
animation: rotateplane 1.2s infinite ease-in-out;
}
#-webkit-keyframes rotateplane {
0% { -webkit-transform: perspective(120px); background-color: #00b16a; }
50% { -webkit-transform: perspective(120px) rotateY(180deg); background-color: #f22613;}
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); background-color: #aaabae; }
}
#keyframes rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
} 50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
} 100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
Two things to consider:
Transitions interpolate smoothly (well, according to the easing function) between keyframes.
If you do not specify an attribute at a keyframe, it will interpolate without interruption over that keyframe.
With those in mind, you can change the keyframes to apply your color change in the middle of your perspective change. In addition, you'll set two keyframes for the color change, very close to each other, to ensure the interpolation happens over a small time slice.
#-webkit-keyframes rotateplane {
0% { -webkit-transform: perspective(120px); background-color: #00b16a; }
24.9% {background-color: #00b16a;}
25.0% {background-color: #f22613;}
50% { -webkit-transform: perspective(120px) rotateY(180deg); background-color: #f22613;}
74.9% { background-color: #f22613; }
75% { background-color: #aaabae; }
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); background-color: #aaabae; }
}
Now, you'll notice that since you have the animation on infinite repeat, that you still get a color transition when the animation loops from 100% to 0%. You'll have to either specify animation-direction: alternate; or adjust your keyframes so that 100% ends at a reasonable tweening point between 100% and 0%.
DEMO using alternate

Resources