I was trying out some CSS animations and found that if I scaled from the bottom left corner of the bounding box, the left side would bounce to the right a little before settling back to where it should be.
Everything else looks correct. The top and the right looks like they are smoothly and evenly moving towards the bottom and left respectively, while the bottom isn't moving at all.
What is happening here? Why is the left side moving?
.shrink {
border-style: solid;
border-width: 1px;
animation-name: title-min;
animation-duration: 1s;
animation-iteration-count:infinite;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#keyframes title-min
{
from { transform: scale(1); }
to { transform: scale(.7); transform-origin: 0% 100% 0; }
}
<body>
<h1 class="shrink">
Hello
</h1>
</body>
This happens on FF, Chrome, IE and Edge. So at least it's consistent. :)
Try placing the transform-origin on the .shrink class.
.shrink {
border-style: solid;
border-width: 1px;
transform-origin: bottom left;
animation-name: title-min;
animation-duration: 1s;
animation-iteration-count:infinite;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#keyframes title-min
{
from { transform: scale(1); }
to { transform: scale(.7); }
}
<body>
<h1 class="shrink">
Hello
</h1>
</body>
Oh. Duh! The Transform origin is different between the beginning and the end. Doing this fixes the problem.
.shrink {
border-style: solid;
border-width: 1px;
animation-name: title-min;
animation-duration: 1s;
animation-iteration-count:infinite;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
#keyframes title-min
{
from { transform: scale(1); transform-origin: 0% 100% 0; }
to { transform: scale(.7); transform-origin: 0% 100% 0; }
}
<body>
<h1 class="shrink">
Hello
</h1>
</body>
Related
I have this little image that I want to rotate continuously or at least have a shorter break between animations.
Here's a gif of the behaviour (it's a bit ugly because of my gif-record-software, but the pause is the thing I wish to highlight here):
My css (less):
.add{
vertical-align: middle;
line-height: 35px;
display: inline-block;
margin-top: 8px;
margin-left:5px;
svg{
fill:#colorOnBright;
max-width: 30px;
max-height: 25px;
vertical-align: middle;
}
}
.animated {
animation-name: rotation;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease;
}
#keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
markup:
<svg class="add animated" click.delegate="Add()">
<use xlink:href="#add"></use>
</svg>
So, how do I get rid of the pause? or alternatively make the pause shorter.
Thanks in advance.
EDIT:
I can't make sense of this.. I've tried recreating the thing in a pen, and it works just fine. Is there some other css-property that interferes with the animation somehow?
https://codepen.io/litari/pen/ajdpjp
edit2:
If I inspect and view the animations, I get this:
So it goes from 0 to 360 degrees at 25% and for the remaining 75% it just stays at 360deg.
If I understand you correctly, replace:
.animated {
animation-timing-function: ease;
}
with:
.animated {
animation-timing-function: linear;
}
The linear timing-function value maintains the same speed throughout the animation.
https://www.smashingmagazine.com/2014/04/understanding-css-timing-functions/#linear
div {
display: inline-block;
}
.animated {
animation-name: rotation;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: ease;
transform-origin: center;
}
#keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
.linear {
animation-timing-function: linear;
}
<div class="animated">+</div>
<p>and with linear:</p>
<div class="animated linear">+</div>
Setting animation-timing-function: linear and -webkit-transform: rotate(360deg) works fine
.animated {
width: 50px;
height: 50px;
border-radius: 50%;
background: black;
animation-name: rotation;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
#keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
.ball{
width: 20px;
height: 20px;
background: red;
border-radius: 50%;
}
<div class="animated">
<div class="ball"></div>
</div>
Found the problem! There was already an animation called rotation somewhere in my project. Changed the name and everything works fine.
Thanks all for your answers
Try using this small change
animation-timing-function: linear;
animation-duration: 3s;
-webkit-transform: rotate(360deg);
Is it possible to comine css transform with some animation?
I have this tarnsform
transform: translate(-10%, 0px); left: 0px;
which works fine to animate slider left, right scrolling
but I would like to add some fade in animation from opacity 0 to 1
if i understand right, you want both translate and opacity to be included in an animation use this :
div {
width: 100px;
height: 100px;
background: red;
animation-name: fromleft;
animation-delay: 0s;
animation-duration: 0.8s;
animation-fill-mode: backwards;
animation-timing-function: ease-out;
}
#keyframes fromleft {
0% {
transform: translateX(-100px);
opacity: 0;
}
100% {
transform: translateX(0px);
opacity: 1;
}
}
<div>
</div>
I needed to implement infinite bounce effect using pure CSS, so I referred this site and ended up doing this.
.animated {
-webkit-animation-duration: 2.5s;
animation-duration: 2.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
animation-iteration-count: infinite;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes bounce {
0%, 20%, 40%, 60%, 80%, 100% {-webkit-transform: translateY(0);}
50% {-webkit-transform: translateY(-5px);}
}
#keyframes bounce {
0%, 20%, 40%, 60%, 80%, 100% {transform: translateY(0);}
50% {transform: translateY(-5px);}
}
.bounce {
-webkit-animation-name: bounce;
animation-name: bounce;
}
#animated-example {
width: 20px;
height: 20px;
background-color: red;
position: relative;
top: 100px;
left: 100px;
border-radius: 50%;
}
hr {
position: relative;
top: 92px;
left: -300px;
width: 200px;
}
<div id="animated-example" class="animated bounce"></div>
<hr>
Now, my only problem is the bouncing element takes a longer rest before it starts bouncing again. How can I make it bounce smoothly just like the bounce effect we get by using jQuery.animate?
The long rest in between is due to your keyframe settings. Your current keyframe rules mean that the actual bounce happens only between 40% - 60% of the animation duration (that is, between 1s - 1.5s mark of the animation). Remove those rules and maybe even reduce the animation-duration to suit your needs.
.animated {
-webkit-animation-duration: .5s;
animation-duration: .5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
animation-iteration-count: infinite;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes bounce {
0%, 100% {
-webkit-transform: translateY(0);
}
50% {
-webkit-transform: translateY(-5px);
}
}
#keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
}
.bounce {
-webkit-animation-name: bounce;
animation-name: bounce;
}
#animated-example {
width: 20px;
height: 20px;
background-color: red;
position: relative;
top: 100px;
left: 100px;
border-radius: 50%;
}
hr {
position: relative;
top: 92px;
left: -300px;
width: 200px;
}
<div id="animated-example" class="animated bounce"></div>
<hr>
Here is how your original keyframe settings would be interpreted by the browser:
At 0% (that is, at 0s or start of animation) - translate by 0px in Y axis.
At 20% (that is, at 0.5s of animation) - translate by 0px in Y axis.
At 40% (that is, at 1s of animation) - translate by 0px in Y axis.
At 50% (that is, at 1.25s of animation) - translate by 5px in Y axis. This results in a gradual upward movement.
At 60% (that is, at 1.5s of animation) - translate by 0px in Y axis. This results in a gradual downward movement.
At 80% (that is, at 2s of animation) - translate by 0px in Y axis.
At 100% (that is, at 2.5s or end of animation) - translate by 0px in Y axis.
Here is code not using the percentage in the keyframes.
Because you used percentages the animation does nothing a long time.
0% translate 0px
20% translate 0px
etc.
How does this example work:
We set an animation. This is a short hand for animation properties.
We immediately start the animation since we use from and to in the keyframes. from is = 0% and to is = 100%
We can now control how fast it will bounce by setting the animation time: animation: bounce 1s infinite alternate; the 1s is how long the animation will last.
.ball {
margin-top: 50px;
border-radius: 50%;
width: 50px;
height: 50px;
background-color: cornflowerblue;
border: 2px solid #999;
animation: bounce 1s infinite alternate;
-webkit-animation: bounce 1s infinite alternate;
}
#keyframes bounce {
from {
transform: translateY(0px);
}
to {
transform: translateY(-15px);
}
}
#-webkit-keyframes bounce {
from {
transform: translateY(0px);
}
to {
transform: translateY(-15px);
}
}
<div class="ball"></div>
In case you're already using the transform property for positioning your element (as I currently am), you can also animate the top margin:
.ball {
animation: bounce 1s infinite alternate;
-webkit-animation: bounce 1s infinite alternate;
}
#keyframes bounce {
from {
margin-top: 0;
}
to {
margin-top: -15px;
}
}
I just built a small animation and it does exactly as I want it to, except a small problem, I have bounceIn animation on 2 HTML elements, my HTML is below:
<div class="test animated bounceInDown">
<span class="animated bounceInDown delay">I am animation</span>
</div>
My CSS:
.test {
height: 200px;
width: 200px;
background-color:yellow;
display: table;
}
.test span {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.animated {
-webkit-animation-duration: 2s;
-o-animation-duration: 2s;
animation-duration: 2s;
}
.delay {
-webkit-animation-delay: 1s;
-o-animation-delay: 1s;
animation-delay: 1s;
}
#-webkit-keyframes bounceInDown {
0%, 60%, 75%, 90%, 100% {
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
100% {
transform: none;
}
}
.bounceInDown {
-webkit-animation-name: bounceInDown;
animation-name: bounceInDown;
}
Now of course span is a child of the div, on the span I have a animation-delay, problem is, the animation on the span has a small bug: it follows the animation of the div and then executes its own animation, I.E. on page load, the span element still bounces in with the div even though I have an animation delay.
I am more interested in WHY this is happening than HOW to solve my problem. Here's a fiddle to see what I am talking about: Fiddle
Nothing is wrong about your animation. Just that the configuration of your animation is not good.
The problem appear because before the animation trigger. The text will be render within the animating parent.
When your text got triggered by animation it will animation on it own. Which mean it will be move up with 3000px.
=> should concern about animation a child in within an animating parent.
When you apply animation to an element, all child elements too undergo the animation. So, in your case, span tag too animates with the parent.
After time in animation-delay's value passes after page load, the animation on child span takes place.
This isn't a bug. Its the way animations work on child elements.
To fix the problem: Just simply use opacity with your animation and animation-fill-mode and it will do the trick
http://jsfiddle.net/ev5ur00n/2/
.test {
height: 200px;
width: 200px;
background-color:yellow;
display: table;
}
.test span {
display: table-cell;
vertical-align: middle;
text-align: center;
opacity: 0;
}
.animated {
-webkit-animation-duration: 2s;
-o-animation-duration: 2s;
animation-duration: 2s;
}
.delay {
-webkit-animation-delay: 1s;
-o-animation-delay: 1s;
animation-delay: 1s;
}
#-webkit-keyframes bounceInDown {
0%, 60%, 75%, 90%, 100% {
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
100% {
transform: none;
opacity: 1;
}
}
.bounceInDown {
-webkit-animation-name: bounceInDown;
animation-name: bounceInDown;
}
.bounceInDown2 {
-webkit-animation-name: bounceInDown;
animation-name: bounceInDown;
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
animation-fill-mode: forwards;
}
<div class="test animated bounceInDown">
<span class="animated bounceInDown2 delay">I am animation</span>
</div>
I was thinking about making an animation where, for example, a circle is falling from the top of the screen/website to the bottom and then it starts to rotate without end. I have the idea but I don't know how to describe it in CSS.
This is what I have done so far and get stuck:
#circle {
border-radius: 50%;
border-top-color: red;
width: 200px;
height: 200px;
bottom: 0px;
#circle {
animation-name: falling;
animation-duration: 5s;
#keyframes falling {
0% {
bottom: 100%;
}
50% {
bottom:0%;
}
100% {
transform: rotate(360deg);
}
I have no idea how I can make an iteration in the "100%" step. Please give me some advice
Demo Fiddle
You can chain animations in CSS by listing their settings in sequence after the relevant CSS animation properties.
Crucially you want to set the animation order, and their respective durations:
animation: falling 1s, rotate 2s;
Then queue them to start sequentially:
animation-delay: 0s, 1s;
So..the above basically says that the falling animation will last 1 second, play it immediately... then play the rotating animation after 1 second (when falling has finished)
It is also important to specify only playing the falling animation once, but loop the rotation:
animation-iteration-count: 1, infinite;
Importantly, dont reset the falling animation state on completion...so the circle stays at the bottom of the page, for the rotation..keep it cyclical:
animation-fill-mode: forwards, both;
HTML
<div id='circle'></div>
CSS
#circle {
border-radius: 50%;
border: 4px solid red;
width: 20px;
height: 20px;
bottom: auto;
position:absolute;
animation: falling 1s, rotate 2s;
animation-delay: 0s, 1s;
animation-iteration-count: 1, infinite;
animation-fill-mode: forwards, both;
-webkit-animation: falling 1s, rotate 2s;
-webkit-animation-delay: 0s, 1s;
-webkit-animation-iteration-count: 1, infinite;
-webkit-animation-fill-mode: forwards, both;
}
#keyframes falling {
0% {
bottom: 100%;
}
100% {
bottom:0%;
}
}
#keyframes rotate {
0% {
-webkit-transform: rotateX(0deg);
}
100% {
-webkit-transform: rotateX(360deg);
}
}
#-webkit-keyframes falling {
0% {
bottom: 100%;
}
100% {
bottom:0%;
}
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotateX(0deg);
}
100% {
-webkit-transform: rotateX(360deg);
}
}