Is there any way / trick to have transition keeping its state just like animation-fill-mode?
<style>
#firstdiv {
width: 100px;
height: 100px;
background: red;
animation: firstdivframe 2s;
animation-play-state: paused;
animation-fill-mode: forwards;
}
#firstdiv:hover {
animation-play-state: running
}
#keyframes firstdivframe {
from { background: red; }
to { background: yellow; }
}
#seconddiv {
width: 100px;
height: 100px;
background: red;
transition: background 2s;
}
#seconddiv:hover {
background: yellow;
}
</style>
<div id="firstdiv"></div>
<br />
<div id="seconddiv"></div>
jsbin
Based on above code, I want the seconddiv to behave just like firstdiv without using any javascript code. The firstdiv will keep its state when the mouse stops hovering or the animation ends, while the seconddiv will always go back to its original state.
No it is not possible to use transitions for this. CSS transitions will only transition between styles (hence the name). If you want to keep a state you have to added a class, for which you always need JavaScript.
I think that this is what your are looking for
#firstdiv {
width: 100px;
height: 100px;
background: red;
animation: firstdivframe 2s;
animation-play-state: paused;
animation-fill-mode: forwards;
}
#firstdiv:hover {
animation-play-state: running
}
#keyframes firstdivframe {
from { background: red; }
to { background: yellow; }
}
#seconddiv {
width: 100px;
height: 100px;
background: red;
animation: seconddiv 2s;
animation-play-state: paused;
animation-fill-mode: forwards;
}
#seconddiv:hover {
animation-play-state: running
}
#keyframes seconddiv {
from { background: red; }
to { background: yellow; }
}
ckeck if it works: jsbin
Please tell me if this is what you are looking for and then i will provide you a more "best-technic" solution with an explanation in each line. (i cannot currently comment).
Yes, of course! Think about setTimeout! You can use setTimeout with the same duration as you have in transition! And the call-back function of setTimeout should set the back the style that you want to keep it!
Related
I am trying to get an object to lead in with one CSS animation key frame set and then have it loop another key frame set forever. Is this possible?
Depends on what you are willing to do for it :)
I don't think that there is a solution to trigger the second animation from within the last keyframe of the first animation.
A possible solution would be to delay the second animation until the first one has finished like this:
#test {
height: 50px;
width: 50px;
background: grey;
animation: 2s firstAnimation forwards, 1s secondAnimation 2s alternate infinite;
/* the "2s" after "secondAnimation" is for the delay */
}
#keyframes firstAnimation {
100% {
width: 100px;
background: red;
}
}
#keyframes secondAnimation {
0% {
height: 50px;
}
100% {
height: 100px;
}
}
<div id="test"></div>
Another possible approach is to verify with javascripts onanimationend and then add the second animation by adding a class for example:
let test = document.getElementById("test")
test.onanimationend = function(event) {
console.log(event) // contains a lot of interesting infos like the name of the animation that ended :)
test.classList.remove("startFirstAnimation")
test.classList.add("startSecondAnimation")
}
#test {
height: 50px;
width: 50px;
background: grey;
}
.startFirstAnimation {
animation: 2s firstAnimation forwards;
}
#keyframes firstAnimation {
100% {
width: 100px;
background: red;
}
}
.startSecondAnimation {
width: 100px !important; /* cheating a little bit here to keep the state of the end of the firstAnimation... */
background: red !important;
animation: 1s secondAnimation alternate infinite;
}
#keyframes secondAnimation {
0% {
height: 50px;
}
100% {
height: 100px;
}
}
<div id="test" class="startFirstAnimation"></div>
I would like to use a single #keyframes rule to animate an element from one state to another and then to get back to the original state when I do an action (with the same animation). I saw that using animation-direction: reverse; is a way to play the animation in reverse. However, when I try to use it, the transitions on my element disappear. If I set a new #keyframes with the reversed state it works fine.
What is the point of animation-direction in this case? I am misunderstanding something?
Is there a way to play an animation in both directions with a single #keyframes rule without loosing the transitions? I can't use transition, I need animation.
Here is a example to play with (hover the squares):
div {
width: 100px;
height: 100px;
animation: fade 0.6s ease-in-out forwards;
margin: 15px;
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
}
#box-1:hover {
animation: fade 0.6s ease-in-out forwards;
animation-direction: reverse;
}
#box-2:hover {
animation: fadeReverse 0.6s ease-in-out forwards;
}
#keyframes fade {
0% { background: red; }
100% { background: blue; }
}
#keyframes fadeReverse {
0% { background: blue; }
100% { background: red; }
}
<div id="box-1">:(</div>
<div id="box-2">:)</div>
It's because you apply the same animation to the element on hover as the animation that is on the default state of the element.
So the element already had that animation with the default direction but then you apply it again with the reverse. But it won't work. I don't really know why this happens. But applying the same animation on an element twice, won't work. So you need 2 different keyframes.
You can use a reverse animation or duplicate the existing one and use it with direction: reverse
Read more here
restart animation
more info here
another article here
If you REALLY want to use just 1 animation this can be solved with javascript by removing and adding an 'animate-me' class . But it still wouldn't be ideal
div {
width: 100px;
height: 100px;
animation: fade 0.6s ease-in-out forwards;
margin: 15px;
display: inline-flex;
align-items: center;
justify-content: center;
color: white;
}
#box-1:hover {
animation: fade2 0.6s ease-in-out forwards;
animation-direction: reverse;
}
#box-2:hover {
animation: fadeReverse 0.6s ease-in-out forwards;
}
#keyframes fade {
0% { background: red; }
100% { background: blue; }
}
#keyframes fade2 {
0% { background: red; }
100% { background: blue; }
}
#keyframes fadeReverse {
0% { background: blue; }
100% { background: red; }
}
<div id="box-1">:(</div>
<div id="box-2">:)</div>
The code below is a part of my code :
.myBox:hover::after {
animation-name: underline;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
It works nicley, but I want to do it vice versa when animation completed, I mean when it finished then width should be 0 again, In fact for this part I want to do it when my element is not hovered. Which property can help me ?
You need to use alternate and run 2 iterations of the animation:
.box {
height:200px;
background:red;
animation: underline 500ms alternate 2 forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
<div class="box">
</div>
Or consider the use of transition if you want the effect on hover:
.box {
height: 200px;
background: red;
width: 0;
transition: 500ms;
}
body:hover .box {
width: 100%;
}
<div class="box">
</div>
You can specify multiple values for animations rather then from and to using percentage:
#keyframes underline {
0%, 100% { width: 0; }
50% { width: 100%; }
}
More detailed information can be found here.
.myBox:hover::after {
animation-name: underline infinite;
animation-duration: 350ms;
animation-fill-mode: forwards;
}
#keyframes underline {
from { width: 0; }
to { width: 100%; }
}
You infinite for this
I was discussing with someone the ability for CSS3 to do animations upon click and hover and I decided to make a little test to show them. I decided to do a bit of boundary pushing and made it so that when you hovered over the animation happened, and when you un-hovered it waited 3 seconds and then ran the animation to put it back.
The problem however is that when the page loads, it runs the "un-hover" animation.
Any ideas for getting around this or another method that's better?
What the below code does is when you hover over the red box it animates is blue. When you un-hover is animates it back red again after 3 seconds. Both of them calculate to a 1 second animation time.
I know this could be fixed with one very simple line of JavaScript, but I'm only interested in seeing if there's a CSS answer.
#-webkit-keyframes makeblue {
0% {
background: red;
}
100% {
background: blue;
}
}
#keyframes makeblue {
0% {
background: red;
}
100% {
background: blue;
}
}
#-webkit-keyframes makered {
0% {
background: blue;
}
75% {
background: blue;
}
100% {
background: red;
}
}
#keyframes makered {
0% {
background: blue;
}
75% {
background: blue;
}
100% {
background: red;
}
}
div {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: makered 4s;
animation: makered 4s;
}
div:hover {
-webkit-animation: makeblue 1s;
animation: makeblue 1s;
background: blue;
}
<div></div>
EDIT 1
Does anyone know if this type of functionality exists, or even potentially planned for the future?:
#keyframes makeblue {
0% {
background: [CurrentValue];
}
100% {
background: blue;
}
}
Having this would be able to fix the problem. If this doesn't exist, I think it should :).
If you are dealing with background or simple css only (not a keyframe animation), you can have it with transition delay, check it out at jsfiddle!:
div {
width: 100px;
height: 100px;
background-color: red;
position: relative;
transition:background-color 0.25s 3s linear;
}
div:hover {
background-color:blue;
transition:background-color 0.25s linear;
}
I have an animation, which is taking care of the fading in and out transition on button hover state.
The problem is that the default animation (-webkit-animation: off-state 1s;) is firing off on page load. How do I make it active only after first hover state?
I know how to achieve this using CSS transitions. I am looking for a solution using animation/keyframes.
HTML
<div class="button"></div>
CSS
.button { background: #000; width: 20px; height: 20px; -webkit-animation: off-state 1s; }
.button:hover { -webkit-animation: on-state 1s; }
#-webkit-keyframes on-state {
0% { height: 20px; }
100% { height: 100px; }
}
#-webkit-keyframes off-state {
0% { height: 100px; }
100% { height: 20px; }
}
Demo
As suggested by #Zeaklous, this can be done using JavaScript, e.g. using jQuery:
$('.button').one('mouseout', function () { $(this).addClass('alt-animation'); });
and moving the animation rule to .alt-animation class:
.button { background: #000; width: 20px; height: 20px; }
.button.alt-animation { -webkit-animation: off-state 1s; }
.button:hover { -webkit-animation: on-state 1s; }
Ideally, there should be CSS only alternative.