I have an element that has css3 animation with keyframes applied to it but still I want to scale this element. But it seems that because transform translate is already applied in the animation transform scale is not working
e.g.: let say I have 4 clouds (div elements) moving from right to left, I want those clouds to be different scales
.x1 {
-webkit-animation-name: moveclouds;
-moz-animation-name: moveclouds;
animation-name: moveclouds;
-webkit-animation-duration: 170s;
-moz-animation-duration: 170s;
animation-duration: 170s;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-transform: scale(0.79);
-moz-transform: scale(0.79);
-ms-transform: scale(0.79);
-o-transform: scale(0.79);
transform: scale(0.79);
}
.x2{ ...}
.x3{...}
.x4{...}
#keyframes moveclouds {
from {
transform: translateX(2400px);
/* note: I'm using vendor prefixes, I just want to simplified it here */
}
to {
transform: translateX(-200px);
}
}
animation works well, scale not
question: anyone got an ide how to enforce the scale ?
I'm using this example http://thecodeplayer.com/walkthrough/pure-css3-animated-clouds-background but tweeking it a bit (see the keyframe difference)
When setting a CSS property, you must set the complete value for the property. So in your example you are wanting to set the TRANSFORM property with multiple types of transforms (translateX and scale). You must set ALL transforms on a single property. Remove the current SCALE styles, and do the following (with vendor prefixes). Yes... you will have duplication. This is a shortcoming of complex CSS3 property values.
#keyframes moveclouds {
from {
transform: translateX(2400px) scale(0.79);
/* note: I'm using vendor prefixes, I just want to simplified it here */
}
to {
transform: translateX(-200px) scale(0.79);
}
}
To expand on this more, if you had an element with multiple background images:
.some-div {
background-image: url("img1.png"), url("img2.png");
}
and you wanted to change img2.png to img3.png on hover, you would have to:
.some-div:hover {
background-image: url("img1.png"), url("img3.png");
}
Related
I'm trying to make a complex animation, so I made the next simple example to ilustrate my problem.
The next code tries to make an object rotate, change its color at 50% of animation and keep it until 100%,
the problem I got is that when it changes from 50% to 100% it doesn't keep the previous keyframe (50%), it becomes transpatent again at 100%.
I've worked with some animation software like blender or animate cc and the default behavior is to keep values of the
properties set in the last keyframe unless you actively change it to something else.
I know that I can set the background property again to red at 100%. but for a real complex animation that would mean repeating A LOT of values,
I'm also aware of the "animation-fill-mode" property which keeps the final state of animation if it is set to "forward",
so I though that if I did that in each step it would behave as I wish but it didn't work :(
Is there a good workaround for this problem without having to repeat each property on every frame?
Can I change the default behaviour?
Note: I thought that if a property is not set on each frame it would default to the initial value (0% frame),
however I didn't set any "transform:rotate" property at 50% and it's not defaulted to 0%'s value, since it interpolates the value between 0% and 100%,
so I have no idea how this really works :/ , some clarification on why does this happen would be really appreceated
.test{
all: unset;
animation-name: rotate_and_change_color;
animation-duration: 3s;
animation-fill-mode: forwards;
animation-timing-function: linear;
animation-direction: normal;
}
#keyframes rotate_and_change_color{
0%{transform: rotate(0deg);
animation-fill-mode: forwards;
}
50%{
background: red;
animation-fill-mode: forwards;
}
100%{transform: rotate(360deg);
animation-fill-mode: forwards;
}
}
One way is to consider multiple animations where you can easily control each property:
.test {
animation-name: rotate, change_color;
animation-duration: 3s;
animation-fill-mode: forwards;
animation-timing-function: linear;
animation-direction: normal;
width:200px;
height:200px;
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes change_color {
50%,
100% {
background: red;
}
}
<div class="test">
</div>
Concerning your note this apply to only the last and first state where if you don't specify any value the computed value will be considered (the initial one or the one defined in the style of the element)
If a 0% or from keyframe is not specified, then the user agent constructs a 0% keyframe using the computed values of the properties being animated. If a 100% or to keyframe is not specified, then the user agent constructs a 100% keyframe using the computed values of the properties being animated.ref
For the other states, you have in fact an interpolation considering the value you have defined and the one automatically done (in case you didn't define the 0% and 100%)
I'm trying to use two consecutive animations for an element using keyframes, but the second animation doesn't start in Chrome if I've set an animation-delay property until I make some interaction, like clicking somewhere. The code works as expected in Firefox.
Is this a bug or is there something that I'm doing wrong?
#-webkit-keyframes to-up {
from {
-webkit-transform: rotate(45deg);
}
to {
-webkit-transform: rotate(0);
}
}
#-webkit-keyframes move {
from {
-webkit-transform: rotate(0);
}
to {
-webkit-transform: translateY(-1000px);
}
}
.animate {
-webkit-animation-name: to-up, move;
-webkit-animation-duration: .5s, 1s;
-webkit-animation-delay: 0, 1.4s;
-webkit-animation-timing-function: ease-in, cubic-bezier(0.6, -0.28, 0.735, 0.045);
-webkit-animation-fill-mode: forwards;
}
Code on Codepen: http://codepen.io/kcmr/pen/Ibrnx
The animation-delay property is commented.
It turns out this is a bug reported nearly a year ago, which astounds me that it has not been fixed.
To fix it they said to change the second's animation-delay to the same length as the duration of the first. For you that would be
animation-delay: 0s, .5s;
They also discuss the possibility of running a second animation during that time (on a different element) which allows the second animation to run. I tested it and confirmed that it also fixes the issue, thus allowing you to have an animation-delay greater that .5s. Following is the animation (that does nothing) that I applied to the container, .wrapper
#keyframes empty {from{display:block;}to{display:block;}}
Good catch on the bug!
I am trying to learn animations in CSS3 but Im stuck with all the documentation out there. I have this code:
h1{
-webkit-animation: moveDown 1.s ease-in-out .6s backwards;
-moz-animation: moveDown 1s ease-in-out 0.6s backwards;
-o-animation: moveDown 1s ease-in-out 0.6s backwards;
-ms-animation: moveDown 1s ease-in-out 0.6s backwards;
animation: moveDown 1s ease-in-out 0.6s backwards;
}
#-webkit-keyframes moveDown{
0% {
-webkit-transform: translateY(-300px);
opacity: 0;
}
100% {
-webkit-transform: translateY(0px);
opacity: 1;
}
}
#-moz-keyframes moveDown{
0% {
-moz-transform: translateY(-40px);
opacity: 0;
}
100% {
-moz-transform: translateY(0px);
opacity: 1;
}
}
#-o-keyframes moveDown{
0% {
-o-transform: translateY(-40px);
opacity: 0;
}
100% {
-o-transform: translateY(0px);
opacity: 1;
}
}
I understand that webkit-animation - animation is the call for each browser.
I dont understand the modeDown. Is that like a variable?
1s is the length of the animations?
ease-in-out I dont understand
.6s is the delay
I dont get the backwards nor am able to find any info on it
Is this for the timing sequence?
#-moz-keyframes moveDown{
0% {
-moz-transform: translateY(-40px);
opacity: 0;
}
100% {
-moz-transform: translateY(0px);
opacity: 1;
}
Ive read this, this and this. Does someone mind explaining this better to me?
}
I dont understand the modeDown. Is that like a variable?
The animation moveDown starts at opacity:0 and -moz-transform:translateY(-40px) and finishes at opacity: 1 and -moz-transform: translateY(0px). This means that it starts completely transparent and shifted 40 pixels above where it normally is and ends at its regular positioning and fully opaque.
#-moz-keyframes moveDown{
0% {
-moz-transform: translateY(-40px);
opacity: 0;
}
100% {
-moz-transform: translateY(0px);
opacity: 1;
}
}
1s is the length of the animations?
Yes.
ease-in-out I dont understand
ease-in-out is an animation-timing-function, this specifies how to transition from 0% to 100% (or the other way). Ease in out will each in and each out of the animation so the change won't be so abrupt, another example is linear which will change in a completely uniform fashion.
There is a handy chart on this page that explains the difference better than words.
.6s is the delay
Yes.
I dont get the backwards nor am able to find any info on it
backwards and forwards are used for animation-fill-mode which says switch direction the animation should go. If forwards is chosen then the animation will run from 0% (transparent) to 100% (opaque), if backwards is chosen then the animation will run from 100% to 0%.
Further reading
The Art of the Web - timing functions
CSS3 animations spec
Mozilla developer - animation
It's often better to read the actual working drafts (or recommendations) from the W3C, since they provide complete information:
I dont understand the modeDown. Is that like a variable?
You could say so, however variables are usually mutable, while moveDown is simply an identifier for an animation. So it's simply the animation's name:
Keyframes are specified using a specialized CSS at-rule. A #keyframes rule consists of the keyword "#keyframes", followed by an identifier giving a name for the animation (which will be referenced using ‘animation-name’), followed by a set of style rules (delimited by curly braces). [source]
1s is the length of the animations?
ease-in-out I dont understand
.6s is the delay
The animation property is a shorthand for several animation-* properties at once:
<single-animation> = <single-animation-name> || <time> || <single-animation-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state>
As you can see the first property is the animation's name (see above), the second the actual length, the third one is the timing-function, in your case ease-in-out. This is basically a bezier-curve which modifies the timing. For example you want to speed up the animation at the beginning and the end, and have a more linear behaviour in the middle.
.6s is indeed the delay between the animations.
I dont get the backwards nor am able to find any info on it
Have a look at animation-fill-mode:
If the value for ‘animation-fill-mode’ is ‘backwards’, then the animation will apply the property values defined in the keyframe that will start the first iteration of the animation, during the period defined by ‘animation-delay’. These are either the values of the ‘from’ keyframe (when ‘animation-direction’ is ‘normal’ or ‘alternate’) or those of the ‘to’ keyframe (when ‘animation-direction’ is ‘reverse’ or ‘alternate-reverse’).
I want to animate two (or more) CSS transform properties separately using keyframe animation like this:
#keyframes translatex {
100% {
transform: translateX(100px);
}
}
#keyframes rotatez {
100% {
transform: rotateZ(80deg);
}
}
HTML:
<div class="rect"></div>
The translatex animation should start with a 0s delay and last for 5 seconds. The rotatez animation should start with a 1s delay and last for 3 seconds. The .rect element starts moving, then after 1 second it starts rotating, then after 3 seconds it stops rotating and after 1 more second it finishes its movement.
Apply animation:
.rect {
animation-name: translatex, rotatez;
animation-duration: 5s, 3s;
animation-timing-function: ease, ease-in-out;
animation-delay: 0s, 1s;
animation-direction: forward, forward;
}
The problem is that only the rotatez animation is applied.
Are there ways to implement the animation using only CSS, such as keyframe animation or transitions, or do I need JavaScript and requestAnimationFrame?
Yes, it is possible. Instead of calling two animation-names, create only one animation with both actions inside:
#keyframes translateXandZ {
100% {
transform: translateX(100px) rotateZ(80deg);
}
}
Look at Google's "Animate your HTML5" presentation.
Here is a workaround, even though it is a bit of a coarse version:
#-webkit-keyframes translateXandZ {
0% {-webkit-transform: translateX(0px) rotateZ(0deg);}
2% {-webkit-transform: translateX(1px) rotateZ(0deg);}
5% {-webkit-transform: translateX(3px) rotateZ(0deg);}
20% {-webkit-transform: translateX(20px) rotateZ(0deg);}
80% {-webkit-transform: translateX(80px) rotateZ(80deg);}
95% {-webkit-transform: translateX(97px) rotateZ(80deg);}
98% {-webkit-transform: translateX(99px) rotateZ(80deg);}
100% {-webkit-transform: translateX(100px) rotateZ(80deg);}
}
Your animation is linear, but to make it ease-in-out, I played with the beginning and ending of the animation. It's still not perfect, but this is the only way I see how you could get what you want.
i am using keyframes to scale an element on my webpage. The problem is that the animation is running perfectly in chrome but its not running in safari. I am providing values at 0% , 80% and 100% in keyframes and everytime the animation ends it goes back to the properties defined at 80% and not 100%. i also used fill-mode to stop animation at last frame but still got no solution.
#-webkit-keyframes leftpageanim {
0%{ -webkit-transform:scale(1);
bottom:-26px;
}
80%{
-webkit-transform:scale(1.8) ; bottom:140px;
}
100%
{
-webkit-transform:scale(1.7); bottom:120px; }
}
after the animation ends its again reverting back to properties of 80%
I did some changes in the code. Look at this jsfiddle. The animation now stops at 100%. That's what you wanted, right?
from:
.animator {
-webkit-animation-name: leftpageanim;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 5s;
to:
.animator {
-webkit-animation: leftpageanim 5.0s ease-in-out forwards;
-webkit-animation-iteration-count: 1;