Perfomance of -webkit-keyframes - css

I have the following CSS animation:
.already-visible {
-webkit-transform: translateY(0);
-webkit-transform: translateX(0);
-webkit-animation: none;
-moz-transform: translateY(0);
-moz-transform: translateX(0);
-moz-animation: none;
}
.come-left-in {
display: block;
-webkit-transform: translateX(-1000px);
-webkit-animation: come-in 1s ease-out forwards;
-moz-transform: translateX(-1000px);
-moz-animation: come-in 1s ease forwards;
}
#-webkit-keyframes come-left-in {
to { -webkit-transform: translateX(0);
}
}
#-moz-keyframes come-left-in {
to { -moz-transform: translateX(0);
}
}
I used it to show the title of each section in the home page as the user scroll down (using scrollspy from Bootstrap 3). But when I scroll while the animation is running, I notice a lack of performance, like a little "jump". Is there a way to avoid this? I am thinking about using left css property animation instead translate transform, but I prefer to consult first this issue.
Thanks.

Use 3d transformations which are generally GPU accelerated (even if your transformation is 2d).
.already-visible {
-webkit-transform: translate3d(0, 0, 0);
-webkit-animation: none;
-moz-transform: translate3d(0, 0, 0);
-moz-animation: none;
}
.come-left-in {
display: block;
-webkit-transform: translate3d(-1000px, 0, 0);
-webkit-animation: come-in 1s ease-out forwards;
-moz-transform: translate3d(-1000px, 0, 0);
-moz-animation: come-in 1s ease forwards;
}
#-webkit-keyframes come-left-in {
to { -webkit-transform: translate3d(0, 0, 0);
}
}
#-moz-keyframes come-left-in {
to { -moz-transform: translate3d(0, 0, 0);
}
}
Read more on HTML5 Rocks
Also, here.

i dont know how webkit calculates transformations, but usually its done by multiplying matrices which can be very painful.
i would use margin-left though, instead of just left.
margin-left would calculate the distance from the parent element, works for me all the time for keyframe animations.

Related

Two separate CSS animations doing the same thing

I'm setting up some predefined animation classes to animate on scroll. They all work, except one I've called slideUp, which seems to behave exactly like slideDown. The animations look exactly like they sound, and are using transforms like so:
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
Seems that no matter what, calling slideUp generates an animation that looks like slideDown, and I can't see any error in my keyframes, nor in execution.
Example of execution:
animation: slideUp 600ms $transition-ease-in 1 forwards, fadeIn 500ms linear 1 forwards;
Thanks!
Edit: I changed the name slideUp to slideup and it started working. This is a from-scratch project, so I can guarantee no conflicts in my code that would have caused that. Any ideas?
Here is an example that may help you. I made it with your animation. Hope this will help. https://jsfiddle.net/ssr3axtr/2/
html :
<div class="box box--1">
</div>
<div class="box box--2">
</div>
CSS :
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.box{
display:inline-block;
width:50px;
height:50px;
background:blue;
transform:translateY(0);
}
.box--1{
animation: slideUp 1s linear 0s infinite forwards;
}
.box--2{
animation: slideDown 1s linear 0s infinite forwards;
}
I think your animation shorthand lists properties in the wrong order. Try this:
#keyframes slideUp {
from {
-webkit-transform: translateY(10%);
transform: translateY(10%);
}
to {
-webkit-transform: translateY(0%);
transform: translateY(0%);
}
}
#keyframes slideDown {
from {
-webkit-transform: translateY(-10%);
transform: translateY(-10%);
}
to {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.btn {
background: green;
color: white;
padding: 2em;
display: inline-block;
animation: 600ms cubic-bezier(0.1, 0.7, 1.0, 0.1) 1 forwards slideUp;
}
<div class="btn">button</div>

CSS background zoom animation jumps on mouse out

I have added a keyframe animation to slowly zoom the background image in and it works perfectly, however when I move mouse out the animation jumps back to the original state instead of zooming out.
#startup.hover:before {
opacity:1;
-webkit-animation: animatedBackground 5s ease-in-out 1;
-moz-animation: animatedBackground 5s ease-in-out 1;
animation: animatedBackground 5s ease-in-out 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes animatedBackground {
0% {
-webkit-transform: scale(1, 1);
-moz-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
100% {
-webkit-transform: scale(1.1, 1.1);
-moz-transform: scale(1.1, 1.1);
-ms-transform: scale(1.1, 1.1);
-o-transform: scale(1.1, 1.1);
transform: scale(1.1, 1.1);
}
}
Am I missing something here?
first of all, is .hover a class you are adding or were you meant to use :hover? Just pointing this out. Assuming this is a class, you should add the transitions animation on the id.
#startup:before {
-webkit-transition: all 5s ease-in-out;
-moz-transition: all 5s ease-in-out;
-o-transition: all 5s ease-in-out;
transition: all 5s ease-in-out;
}
..this is why it's breaking when you are hovering out. There's no transition animation without the class!
You dont need such an advanced tool as a keyframes to make this effect.
It is easily achivable with transitions, here is an example.
https://jsfiddle.net/vqL3stjz/
.animable{
width: 100px;
height: 100px;
background-color: #000;
transition: all 500ms;
}
.animable:hover{
transform: scale(1.3, 1.3);
transition: all 500ms;
}
And if you need to make it with keyframes, then i suggest just applying reverse animation to unhovered element.
However, you will need to use some javascript then, to prevent side effect like animation running on the element right after it is loaded etc.
TL;DR Better use tranistions, unless you really need to use keyframes.

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

Why don't my CSS animations run simultaneously?

I am working on a proof of concept. I am trying to duplicate Tinder UX using HTML and CSS, here's my link: CodePen
The problem is that I have two main animations which should run in parallel with each other. But they run sequentially, one after another. Is there a way to run them at the same time?
animation on profile picture.
.tinder-profile
{
-webkit-animation: avatar 0.8s;
animation: avatar 0.8s;
}
#keyframes avatar {
0% {
-webkit-transform: scale(0.8, 0.8);
transform: scale(0.8, 0.8);
}
60% {
-webkit-transform: scale(1.1, 1.1);
transform: scale(1.1, 1.1);
}
100% {
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
}
and pulsing circles in the background:
<pre>
.tinder-ping1{
-webkit-animation: ping 3s ease-in-out infinite;
animation: ping 3s ease-in-out infinite;
z-index:9;
}
#keyframes ping {
0% {
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
opacity: 0.0;
}
40% {
opacity: 1.0;
}
100% {
-webkit-transform: scale(1.1, 1.1);
transform: scale(1.1, 1.1);
opacity: 0.0;
}
}
</pre>
Here is a link to the EditPen, where you can see all the code: CodePen
It has to do with the initial position of your tinder-ping elements. They all start full sized and so effectively the animations don't appear to be working until the third one finally resizes to be small. You'll have to play around with the actual settings, but setting pings 1, 2, and 3 to have
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
opacity: 0;
As initial values makes it better. You might also need to test out z-indexes, but that is a place to start.
In essence, your third ping is hiding the other two because it is 520x520 pixels until after the animation delay.

Why isn't -moz-animation working?

The following CSS works fine in Webkit. Haven't checked it in Opera, but I know it's not working in Firefox. Can anybody tell me why?
The correct classes are definitely getting applied to my HTML (inspected it with Firebug, and I do see the -moz-animation: 500ms ease 0s normal forwards 1 arrowRotateDot property on .arrow).
This also doesn't work in IE9, although I did originally have -ms-animation:... and -ms-transform:.... I thought it was supposed to work in IE9, but when it didn't I just assumed that IE didn't support these yet. However, now that it's not working in Firefox, maybe something else is going on.
.page.updatesPodcasts > .mainContent > .content .contentUpdates .disc.dot .dvd .arrow {
-webkit-animation: arrowRotateDot 500ms forwards;
-moz-animation: arrowRotateDot 500ms forwards;
-o-animation: arrowRotateDot 500ms forwards;
animation: arrowRotateDot 500ms forwards;
}
.page.updatesPodcasts > .mainContent > .content .contentUpdates .disc.f2 .dvd .arrow {
-webkit-animation: arrowRotateF2 500ms forwards;
-moz-animation: arrowRotateF2 500ms forwards;
-o-animation: arrowRotateF2 500ms forwards;
animation: arrowRotateF2 500ms forwards;
}
#-webkit-keyframes arrowRotateDot {
100% {
left:-18px; top:182px;
-moz-transform: scale(1) rotate(-30deg);
-webkit-transform: scale(1) rotate(-30deg);
-o-transform: scale(1) rotate(-30deg);
transform: scale(1) rotate(-30deg);
}
}
#-webkit-keyframes arrowRotateF2 {
0% {
left:-18px; top:182px;
-moz-transform: scale(1) rotate(-30deg);
-webkit-transform: scale(1) rotate(-30deg);
-o-transform: scale(1) rotate(-30deg);
transform: scale(1) rotate(-30deg);
}
100% {
left:115px; top:257px;
-moz-transform: scale(1) rotate(-90deg);
-webkit-transform: scale(1) rotate(-90deg);
-o-transform: scale(1) rotate(-90deg);
transform: scale(1) rotate(-90deg);
}
}
Your animations are not working in Firefox because you are using #-webkit-keyframes, which only applies to Webkit browsers, i.e. Chrome and Safari. The (somewhat) cross-browser way to do animation keyframes is:
#keyframes animationName {
/* animation rules */
}
#-moz-keyframes animationName {
/* -moz-animation rules */
}
#-webkit-keyframes animationName {
/* -webkit-animation rules */
}
Opera and Internet Explorer do not currently support the #keyframes rule.
Skyline is correct. Firefox does not support this, so you will need additional code to get the same or similar effects if they exist without webkit.
Also, here is some additional information that might help you with your code or help you in deciding where to go from this point with your code if adding additional code is not an option (I ended up changing how I code to keep from being overwhelmed with code):
http://caniuse.com/#
http://www.quirksmode.org/webkit.html

Resources