`animation-fill-mode: none;` not working - css

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

Related

Is animation-fill-mode: forwards better than using from/to in keyframes?

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>

Transition only for translate property

I have two transform operations (rotate and translate) and I want to make transition for translate only (rotate have to be instant).
Some suggestions? I prefer pure css.
Use keyframes to reach your desired effect, in addition to animation-fill-mode to keep the computed styles when the animation is finished.
.object {
width: 50px;
height: 50px;
background-color: #F00;
animation-fill-mode: forwards;
}
.object:hover {
animation: move 1s;
animation-fill-mode: forwards;
}
#keyframes move {
0% {
transform: translateY(0px) rotate(0deg);
}
1% {
transform: rotate(45deg);
}
100% {
transform: translateY(25px) rotate(45deg);
}
}
<div class="object"></div>

Keyframe CSS animation overwrites hover transition

I am afraid there are similar questions to this but I didn’t found a concrete solution, so I created a fiddle:
http://jsfiddle.net/Garavani/yrnjaf69/2/
<div class= "category_item">
<div class= "cat_button">
<span class="title_cat">TEXT</span>
</div>
</div>
CSS:
.category_item {
position: absolute;
background-color: #999;
top: 100px;
left: 50px;
width: 200px;
height: 200px;
/* seems to be overwriten by animation keyframes */
-webkit-transition: -webkit-transform 0.215s ease-in-out;
transition: transform 0.215s ease-in-out;
cursor: pointer;
}
.category_item:hover {
-webkit-animation-name: easeBack;
animation-name: easeBack;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes easeBack {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
50% {
-webkit-transform: translateY(-50px);
transform: translateY(-50px);
}
100% {
-webkit-transform: translateY(-30px);
transform: translateY(-30px);
}
}
.cat_button {
position: absolute;
width: 200px;
height: 55px;
bottom: 0;
border: 2px solid #fff;
color: #fff;
-webkit-transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
transition: background 0.215s ease-in-out, border 0.215s ease-in-out, color 0.215s ease-in-out;
}
.category_item:hover .cat_button {
background: #fff;
border-color: #fff;
color: #511c5b;
}
In this (simplified) animation everything works fine except for when the mouse leaves the entire box. The animation starts from it original state, but abruptly.
The basic transition time (and ease) is ignored because it seems the keyframes have higher importance and overwrite it.
What I need is the keyframe animation triggering AND when the mouse leaves it should turn back to the original state smoothly.
Is there a solution for this
1) in pure CSS
2) maybe with some little javascript only?
Thanks in advance for help and ideas!
EDIT:
After implementing the solution offered kindly by Toni this is the correct fiddle:
http://jsfiddle.net/yrnjaf69/40/
Thanks again Toni!
EDIT 2:
Sadly, yet, there is one question left. The part with the keyframes is not executed on Firefox even though I added all the -moz- vendors, too, in this fiddle:
http://jsfiddle.net/dr6Ld0wL/1/
Why?
PS: As far as I tested for now it works even in Opera (Beta). Only browser resisting is Firefox
EDIT 3:
The correct (working) code is now in this fiddle:
http://jsfiddle.net/dr6Ld0wL/16/
The keyframes also need to be explicitly divided in vendor prefixes. Jesus Christ. Those prefixes…
Here is a jsfiddle that achieves this.
.demo-hover {
position: relative;
margin: 100px;
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
.demo-hover:hover {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
#keyframes complexProcess {
/* keyframes */
}
#keyframes complexProcessReversed {
/* keyframes (opposite) */
}
The animation out is assigned in the css in the main class, then the hover state kicks in on hover and css re-applies the original class properties on unhover.
The animation does trigger backwards on page load, so you might like to think of tweaking your animation to take this into account, like this example, pinched from this answer. Alternatively, use javascript (or jquery), like this example where the animations are triggered by adding and removing classes to the target using jquery:
JavaScript
$('.demo-hover').hover(
function() {
// mouse in
$(this).removeClass('forwards--reversed').addClass('forwards');
},
function() {
// mouse out
$(this).removeClass('forwards').addClass('forwards--reversed');
}
);
CSS
.forwards {
animation: complexProcess 2s ease-in forwards;
width: 100px;
height: 100px;
background-color: #732;
}
.forwards--reversed {
animation: complexProcessReversed 2s ease-in forwards;
width: 160px;
height: 160px;
background-color: #88d;
}
Also, I'd use #keyframe or transition. Use transition if you just need a simple even change from n to m but when things are more complex, such as one thing changing evenly over 100% but another thing not starting until 50% off the animation has played, then use a #keyframe
Using both will cause confusion, especially if you're trying to animate the same properties.
Finally css vendor prefixes are required

How can I create an infinite scale mouseover animation with a smooth mouseout effect with css?

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.

Multiple CSS3 animation on the same element

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

Resources