I have a little problem in here related with CSS3 animations.
I want to run animation and than run it again reversed. To make this I'm using:
-webkit-animation: moveKv 1s forwards, moveKv 1s forwards 2s reverse;
And that's how my keyframes looks like:
#-webkit-keyframes 'moveKv' {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(180deg); }
}
Everything works fine in Chrome canary, but it don't work in stable chrome. For some reason as soon as I add delay animation stops working.
Here's jsfiddle
EDIT: Okay, let me show you what I want eventually.
http://jsfiddle.net/57dw8/5/
EDIT 2: Actually the reason was pretty simple. Use 2 animations with same name wasn't supported in stable chrome at the moment post was created.
Not the cleanest way, but since your animation is that simple: why not using two animations (one forward, one backward) with the same duration and apply 1T delay to the second one (to start from the end of the first) ?
Running Example
.wrap { position: relative; }
.banner {
position : absolute;
top : 0;
left : 0;
width : 100px;
height : 100px;
background : #000;
border-left : 10px solid red;
border-right : 10px solid green;
border-bottom : 10px solid blue;
border-top : 10px solid yellow;
-webkit-animation : moveForward 1s, 1s moveBackward 1s;
}
#-webkit-keyframes 'moveForward' {
0% { -webkit-transform : rotate(0deg); }
100% { -webkit-transform : rotate(180deg); }
}
#-webkit-keyframes 'moveBackward' {
0% { -webkit-transform : rotate(180deg); }
100% { -webkit-transform : rotate(0deg); }
}
I've prefixed the code in the Fiddle with Nettus Prefixr, so you can run it crossbrowser now.
Here is the answer....
fiddle: http://jsfiddle.net/nikhilvkd/57dw8/3/
.banner {
position: absolute;
top: 0; left: 0;
width: 100px;
height: 100px;
-webkit-animation: moveKv infinite 2000ms;/*change here*/
background: #000;
}
#-webkit-keyframes moveKv {
0% { -webkit-transform: rotate(0deg); }
50% { -webkit-transform: rotate(180deg); }
100% { -webkit-transform: rotate(0deg); }
}
You should use two properties -
animation-direction: alternate;
animation-iteration-count: 2;
animation-direction - Configures whether or not the animation should alternate direction on each run through the sequence or reset to the start point and repeat itself.
animation-iteration-count - Configures the number of times the animation should repeat; you can specify infinite to repeat the animation indefinitely.
Must read: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations
Related
For this example, I'll use a simple box that, as an animation, pops into view using opacity and transform: translate().
I can do this in two ways:
Set the box's initial CSS to opacity: 0 and transform: translate(10px), then write a keyframes that just sets the to property. Then, persist the end state of the animation using animation-fill-mode: forwards (specified in the shorthand).
.animation {
width: 100px;
height: 100px;
background: green;
animation: slide-in .5s ease-in-out forwards;
opacity: 0;
transform: translateY(10px);
}
#keyframes slide-in {
to {
opacity: 1;
transform: translateY(0);
}
}
<div class="animation"></div>
The second way to do this is to specify the initial state in the keyframes instead, and not on the element itself. I specify a from and a to state, and leave everything to the animation.
.animation {
width: 100px;
height: 100px;
background: green;
animation: slide-in .5s ease-in-out;
}
#keyframes slide-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
<div class="animation"></div>
Both ways seem to work well and so my question is:
Is one of these options better than the other?
I don't see any advantages/disadvantages that aren't based on opinion, so I'm looking for factual advantages (performance?, accessibility?)
If a user has disabled transitions and/or animations, using the first approach the element would be not visible at all because you defined opacity: 0 as a property of the element and not inside the keyframes.
So, the second approach at least ensures that the element is always visible, even when the animation can't run because of user's settings.
Note that this is not strictly related to the animation-fill-mode property, since you could still use it by slightly changing the CSS of the first snippet:
.animation {
width: 100px;
height: 100px;
background: green;
animation: slide-in .5s ease-in-out forwards;
}
#keyframes slide-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
<div class="animation"></div>
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 problem and the answer I found are not precise enough.
I have 2 DIV. A div at left:-100%; and a div at left:100%;
I would like in ONE animation, animate those div to smoothly go from their actual Left, to left:0%;
i tried adding just
.animSlide{
animation-duration: 0.5s;
animation-iteration-count: 1;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-name: anim;
}
#keyframes anim {
to {
left: 0%;
}
}
But this brake all steps on animation. I mean, after 0.5s my div go from actual left to 0%;
So, is there a way to say
#keyframes anim {
from{
left:current%;
}
to {
left: 0%;
}
}
Thx for help
EDIT : The ABOVE code should work. So my problem come from another part of the code...
This is what i do basically : https://jsfiddle.net/Crocsx/rwyt400n/
Answer based on the JSFiddle provided in comment by the author.
This is not a very good answer because I only have an hypothesis about the problem, however I have a solution.
The problem, I think, is that the value of left after the animation is "virtual". When you start the second animation (by putting the class "slide_to_right") it look at the real value which is still 100%, even though you see it as 0%, and start the animation from this point (that's why it is not animated from 0%).
Because you are using JS to change the state of the elements, instead of using animations, you can use transitions. It will allow your element to be animated automatically when changing between the 2 states and it is easier to set in this case (less code).
Thanks to this property, all you have to do is set the transition property on your sliding element. And then change its state in JS. In this case you want to alternate between left:100% and left:0%. So the transition property is written like this : transition: left 5s;.
To set the different left values, you can directly change the style in JS. Or have a class prepared in your css and add this class to your element. In this case, 2 classes .left and .right work great.
The transition will take care of the animation.
Here is the code : https://jsfiddle.net/rwyt400n/4/ (I changed the id to classes).
I think this is what you're looking for:
#-moz-keyframes dropHeader {
0% {
-moz-transform: translateY(-100px);
}
100% {
-moz-transform: translateY(0);
}
}
#-webkit-keyframes dropHeader {
0% {
-webkit-transform: translateY(-100px);
}
100% {
-webkit-transform: translateY(0);
}
}
#keyframes dropHeader {
0% {
transform: translateY(-100px);
}
100% {
transform: translateY(0);
}
}
you can specify a css property value that you want the animation to begin with, and end with. you can also split this keyframe into more than just 0% and 100%.
For ex.
#keyframes dropHeader {
0% {
transform: translateY(-100px);
}
25% {
transform: translateY(-75px);
}
50% {
transform: translateY(-50px);
}
75% {
transform: translateY(-25px);
}
100% {
transform: translateY(0);
}
}
See this fiddle.
HTML:
<div class="wrapper">
<div class="div1"></div>
<div class="div2"></div>
</div>
CSS:
.wrapper {
height: 200px;
width: 100px;
margin-left: 100px;
}
.div1 {
width: 100px;
height: 100px;
background: red;
position: relative;
left: -100%;
animation: anim 5s;
}
.div2 {
width: 100px;
height: 100px;
background: black;
position: relative;
left: 100%;
animation: anim 5s;
}
#keyframes anim {
to {
left: 0;
}
}
I'm coding a CSS3 effect fired on mouseover; this effect simply animate an inner div scaling it endlessly.
All works great, but when I move the mouse away the div suddenly return to its original size. I would like to add a smooth effect to scale the div back.
I already checked the suggestion of this post:
Make CSS Hover state remain after "unhovering"
Unfortunately the code posted doesn't work :(
In my opinion my issue could be related with the "infinite" loop of the scale effect.
THe goal I would like to gain is the on mouse-out the image could return to its original size smoothly.
Here's the code: https://jsfiddle.net/9dtqpsLa/1/
CSS
#keyframes imageZoom{
0% { transform: scale(1); }
50% { transform: scale(1.24); }
100% { transform: scale(1);}
}
#-moz-keyframes imageZoom{
0% { -moz-transform: scale(1);}
50% { -moz-transform: scale(1.24); }
100% { -moz-transform: scale(1); }
}
#-webkit-keyframes imageZoom{
0% { -webkit-transform: scale(1); }
50% {-webkit-transform: scale(1.24); }
100% { -webkit-transform: scale(1); }
}
#-ms-keyframes imageZoom{
0% { -ms-transform: scale(1); }
50% { -ms-transform: scale(1.24); }
100% { -ms-transform: scale(1); }
}
.article:hover .imageWrapper {
animation: imageZoom linear 10s;
animation-iteration-count: infinite;
-webkit-animation: imageZoom linear 10s;
-webkit-animation-iteration-count: infinite;
-moz-animation: imageZoom linear 10s;
-moz-animation-iteration-count: infinite;
-ms-animation: imageZoom linear 10s;
-ms-animation-iteration-count: infinite;
transform-origin: 50% 80%;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
}
HTML
<div class="article">
<div class="imageWrapper">
</div>
</div>
Please, could you help me?
Thanks so much
GOALS:
1. Have the image animate expansion and contraction on hover
2. Have the image animate to original state on mouseleave
PROBLEMS:
With CSS, I don't know how to use both an animation and a transition. The animation is the pulsing on hover. The transition is the return to default animation. The only way I could envision doing it is with JS. See each section for notes
https://jsfiddle.net/Bushwazi/9dtqpsLa/5/
HTML:
notes: same as example provided
<div class="article">
<div class="imageWrapper"></div>
</div>
CSS:
notes:
1. animation removed.
2. The scale is only fired with the existence of [data-dir='expand'].
3. transform-origin and transition moved into the default state of .imageWrapper
4. need to add prefixes
.article[data-dir='expand'] .imageWrapper {
transform:scale(1.24)
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
transition:all 10.0s linear 0.0s;
}
JAVASCRIPT:
notes:
1. all new
/*
1. on hover aka 'mouseenter' start the animation
2. 10 seconds in, change direction of the animation based on the `isHovering` variable
3. on exit aka 'mouseleave', return to default
*/
var thisArticle = document.querySelector('.article'),
thisTimer = '',
isHovering = false;
thisArticle.addEventListener('mouseenter', function(){
console.log('mouseenter');
thisArticle.setAttribute('data-dir', 'expand');
thisTimer = setInterval(fireAnimation, 10000);
isHovering = true
}, false);
thisArticle.addEventListener('mouseleave', function(){
console.log('mouseleave');
thisArticle.removeAttribute('data-dir');
isHovering = false;
clearInterval(thisTimer);
}, false);
var fireAnimation = function(){
if(isHovering){
if(thisArticle.getAttribute('data-dir') === 'expand'){
thisArticle.removeAttribute('data-dir');
} else {
thisArticle.setAttribute('data-dir', 'expand');
}
} else {
clearInterval(thisTimer);
}
alert('change direction');
}
MORE IDEAS
1. I used a data attribute, but I would prefer to use classList. Wasn't sure how to incorporate that into the fiddle in 30 seconds, so skipped it.
2. The return to default animation has no awareness of the scale when you leave, so it takes 10 seconds no matter what. I'm sure there is a way to make this better.
Once you the mouse is moved away from the element, the styles in the :hover pseudo class gets removed from your element, effectively putting it back where it started.
What you want to do is start and pause the animation:
Here is your fiddle, I edited it a bit and exploded the short-hand and removed -webkit, -ms, etc:
https://jsfiddle.net/9dtqpsLa/4/
#keyframes imageZoom {
100% {
transform: scale(4);
}
}
.article:hover .imageWrapper {
animation-play-state: running;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
animation-name: imageZoom;
animation-duration: 2s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: both;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
animation-play-state: paused;
}
Notice that all the animation logic has moved to the base class, and the :hover only kicks off the animation.
According to https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode, the animation-fill-mode: none; should not apply style of the first frame to the element before the animation starts. However, animation-fill-mode: backwards should.
But in this demo of the below code, it seems like none is doing the job backwards should. Why?
/* I have autoprefixer enabled */
div {
width: 100px;
height: 100px;
background-color: red;
transform: translate(0, 0);
animation: someAnimation 1s linear 1s;
animation-fill-mode: none;
-webkit-animation-fill-mode: none;
}
#keyframes someAnimation {
0% {
transform: translate(50px, 50px);
}
100% {
transform: translate(100px, 100px);
}
}
You misspelled animation-fill-mode in the first statement
You don't have a -webkit- prefix for the animation and transition properties nor do you enable prefix free, so webkit is not being served
Once you fix those they work differently as they should