CSS animation forwards is preventing css transitions - css

I am setting my CSS animation type to forwards so that the finished frame of the animation is the default state when finished.
But now, the transition that animates the same property (transform) is not working anymore...
I have to use forwards because otherwise the opacity resets to 0 after animating.
How can I enable a transition as soon as an animation has finished? I am looking for a CSS-only option without javascript.
CSS
album {
opacity: 0;
animation:movein 0.6s forwards;
transition: all 0.3s ease-in-out;
}
album:hover {
transform:scale(1.05); // this doesn't work
box-shadow: 0px 0px 45px rgba(0,0,0,0.5); // this works
}
#keyframes movein {
from {
opacity:0;
transform: translateX(-100px);
}
to {
opacity:1;
transform: translateX(0px);
}
}
album:nth-child(2) {
animation-delay: 0.2s; // delay keeps opacity 0 for a while
}
album:nth-child(3) {
animation-delay: 0.4s; // delay keeps opacity 0 for a while
}

One solution could be to split up your animation. Only the fadein animation has animation forwards.
album {
opacity: 0;
animation:movein 0.6s, fadein 0.6s forwards;
transition: all 0.3s ease-in-out;
}
#keyframes movein {
from {
transform: translateX(-100px);
}
to {
transform: translateX(0);
}
}
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}

Related

Is there a conflict rule in css? My fadein keyframes works fine but my slidedown doesn't

Im using react and css. In my css file I create 2 animations:
#keyframes fadein {
0% {
visibility: hidden;
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
visibility: visible;
opacity: 1;
}
}
#keyframes slidedown {
0% {
transform: translateY(0%);
}
100% {
transform: translateY(30%);
}
}
.welcome__text {
padding: 3rem;
animation:
/* slidedown 2s ease 0s 1 normal forwards; => This one doesn't work */
/* fadein 1s ease-in 0s 1 normal forwards; => This one works */
}
here is my react file :
const Home = () => {
return (
<div className='homepage'>
<div className='welcome__text'>
<h1>Welcome</h1>
<h3> to Net's Web Game </h3>
</div>
</div>
)
}
export default Home;
My fadein keyframes works fine but my slidedown doesn't. And I don't know why. Is there any conflict css rule ?
If you're calling 2 animations on 1 element you need to separate them with commas, otherwise the last one (fadein) will just take priority as CSS is read from top to bottom, thus resulting in only 1 animation. For the animation properties, just separate them with commas as well:
#keyframes fadein {
0% {
visibility: hidden;
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
visibility: visible;
opacity: 1;
}
}
#keyframes slidedown {
0% {
transform: translateY(0%);
}
100% {
transform: translateY(30%);
}
}
.welcome__text {
padding: 3rem;
animation: slidedown 2s, fadein 1s;
animation-fill-mode: forwards;
animation-timing-function: ease 0s, ease-in 0s;
animation-direction: normal;
/* slidedown 2s ease 0s 1 normal forwards; => This one doesn't work */
/* fadein 1s ease-in 0s 1 normal forwards; => This one works */
}
<div class="welcome__text">hey there!</div>

Animate DOM Element on removal of Element

I have to animate the Toast Notifications, I am currently using the transition to show it coming from the top. It looks good to me, I want to stop the sudden moving of the other toast notifications so harshly, any way they can cover space smoothly ?
Current CSS :
.slds-transition-hide {
transition: all 0.5s;
}
.slds-transition-show {
transition: all 0.5s;
animation: show 0.5s forwards;
}
#keyframes show {
0% {
transform: translateY(-50px);
}
25% {
transform: translateY(-40px);
}
50% {
transform: translateY(-20px);
}
75% {
transform: translateY(-10px);
}
100% {
transform: translateY(0px);
}
}
.slds-notify {
pointer-events: all;
}
Demo:
The elements are removed 0.5s after the fade out transition.
Additional Info: I am using LWC OSS, which is developed on Node JS.
In order to achieve the same, I added another animation on closing, so basically whenI want to hide I am adding slds-transition-hide.
I have added another animation to the original fadeout of transition-hide of SLDS lib where I am dereasing the max-height so the other elements can slide up.
.slds-transition-hide {
transition: all 0.5s;
animation: hide 0.5s forwards;
}
.slds-transition-show {
transition: all 0.5s;
animation: show 0.5s forwards;
}
#keyframes hide {
0% {
max-height: 150px;
transform: translateY(0px);
}
25% {
transform: translateY(-10px);
}
50% {
transform: translateY(-20px);
}
75% {
transform: translateY(-40px);
}
100% {
max-height: 0px;
padding: 0px;
transform: translateY(-50px);
}
}

CSS animation and animation on :hover

I want to have the beginning animation on load and then on :hover to add another animation. The problem is, after I leave the element(not hovering) it goes back to its first animation and repeats it.
Is there any way to avoid this from happening?
Problem video :
https://youtu.be/uCZdo4FsCj8
Code :
.char {
animation: slide-down 2s forwards cubic-bezier(0, 1.18, .82, 1.02);
animation-delay: calc(0s + (0.1s * var(--char-index)));
animation-iteration-count: 1;
opacity: 1;
#keyframes slide-down {
from {
transform: translate(-125%, 125%);
opacity: 1;
}
to {
transform: translate(0%);
opacity: 1;
}
}
&:hover {
animation: newAnim 0.4s forwards linear;
color: red;
#keyframes newAnim {
from {
transform: scale(1);
}
to {
transform: scale(1.2);
}
}
}
}
You cannot do it without using JavaScript. When :hover happens, the animation-iteration-count gets reset. This in turn causes the first animation to repeat after letting go of hovering. So you will have to use some JavaScript to get it working.
Have you considered using the animation just for the initial movement, and transitions for the :hover effect? This way, the animation-iteration-count is not reset after unhovering. Essentially add the following css code:
.char {
...your animations for initial loading
transition: color 0.4s linear, transform 0.4s linear;
}
.char:hover {
transform: scale(1.2);
color: red;
}
An example of such solution can be found in this codepen.

How to run the same animation when switching classes without JavaScript

I have an element which functions as a tri-state checkbox. I want to run an animation on that element whenever the state changes. Essentially, the element starts with no classes attached to indicate the first state. Then I add a class for one state, then remove that class and add a different one for the second state.
It works on the first click but the animation doesn't play on subsequent clicks. Here's what I have so far:
$('button').click(function() {
var $div = $('div');
if (!$div.hasClass('is-colored')) {
$div.addClass('green is-colored');
} else {
$div.toggleClass('green red');
}
});
#keyframes Animation {
from {
opacity: 0;
transform: scaleX(0) scaleY(0);
}
to {
opacity: 1;
transform: scaleX(1) scaleY(1);
}
}
.green {
background-color: #0F0;
-webkit-animation: Animation 0.25s linear forwards;
-moz-animation: Animation 0.25s linear forwards;
animation: Animation 0.25s linear forwards;
}
.red {
background-color: #F00;
/* I tried applying the animation on the second state but this isn't working */
-webkit-animation: Animation 0.25s linear forwards;
-moz-animation: Animation 0.25s linear forwards;
animation: Animation 0.25s linear forwards;
}
div {
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>Change Color</button>
I know it's possible to restart an animation with JavaScript and as of 3 years ago it didn't seem to be possible to do this without JavaScript.
In short, is it possible to perform the same animation on the same element multiple times using only CSS and toggling classes (i.e, no timeout required)?
What's happening is because the state never gets a reset so the animation doesn't kick in again. What you want to do is remove the color class as it resets, "wait" (0 seconds) then have the new class kick in for the animation.
The change is like this for green, see below for full changes:
$div.removeClass('green');
setTimeout(function() {
$div.addClass('red');
}, 0);
Edit: To do this without javascript delay. The only way is to create another version of the animation so it constantly runs a different animation:
$('button').click(function() {
var $div = $('div');
if (!$div.hasClass('is-colored')) {
$div.addClass('green is-colored');
} else {
$div.toggleClass('green red');
}
});
#keyframes Animation {
from {
opacity: 0;
transform: scaleX(0) scaleY(0);
}
to {
opacity: 1;
transform: scaleX(1) scaleY(1);
}
}
#keyframes Animation2 {
from {
opacity: 0;
transform: scaleX(0) scaleY(0);
}
to {
opacity: 1;
transform: scaleX(1) scaleY(1);
}
}
.green {
background-color: #0F0;
-webkit-animation: Animation 0.25s linear forwards;
-moz-animation: Animation 0.25s linear forwards;
animation: Animation 0.25s linear forwards;
}
.red {
background-color: #F00;
/* I tried applying the animation on the second state but this isn't working */
-webkit-animation: Animation2 0.25s linear forwards;
-moz-animation: Animation2 0.25s linear forwards;
animation: Animation2 0.25s linear forwards;
}
div {
width: 100px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<button>Change Color</button>

FadeOut/FadeIn animations before/after ngAnimate

I have this form on plunker and a struggling with adding a fade animation.
What I want to do is, before the keyframe animation starts have the content fade out. And when the new view appears, I want the the keyframe animation to finish and than an animate.css animation to run (fadeInUp for example).
So the view will animate and then the content inside the view will animate, If somebody can help me with this I would really appreciate it.
my current animation is using the following keyframe animation:
#-webkit-keyframes slideOutLeft {
0% {
transform: scaleY(1) scaleX(1);
}
20% {
transform: scaleY(0.01) scaleX(1);
}
40% {
transform: scaleY(0.005) scaleX(0.5);
}
50% {
opacity: 1;
}
100% {
transform: scaleY(0.005) scaleX(0.5);
opacity: 0;
}
}
#-webkit-keyframes slideInRight {
0% {
transform: scaleY(0.005) scaleX(0.5);
background: rgba(0,188,140,1);
opacity: 0;
}
50% {
transform: scaleY(0.005) scaleX(0.5);
background: rgba(0,188,140,1);
z-index: 1;
opacity: 0;
}
70% {
transform: scaleY(0.005) scaleX(1);
background: rgba(0,188,140,1);
opacity: 1;
}
100% {
transform: scaleY(1) scaleX(1);
}
}
Running on ng.enter and ng.leave
/* enter animation */
#form-views.ng-enter {
-webkit-animation:slideInRight 2s both ease;
-moz-animation:slideInRight 2s both ease;
animation:slideInRight 2s both ease;
}
/* leave animation */
#form-views.ng-leave {
-webkit-animation:slideOutLeft 2s both ease;
-moz-animation:slideOutLeft 2s both ease;
animation:slideOutLeft 2s both ease;
}
EDIT 1:
I have updated the code here
using:
#form-views.ng-enter * {
-webkit-animation:fadeIn 2s both ease 3s;
-moz-animation:fadeIn 2s both ease 3s;
animation:fadeIn 2s both ease 3s;
}
#form-views.ng-leave * {
-webkit-animation:fadeOut 0.5s both ease;
-moz-animation:fadeOut 0.5s both ease;
animation:fadeOut 0.5s both ease;
}
And this is the animation:
#keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#keyframes fadeOut { from { opacity:1; } to { opacity:0; } }
The code appears and disappearing at the correct time but doesn't animate the opacity.
I would try adding separate animation for fadeIn/Out and using the css animation delay to trigger one after the other. E.G:
/* enter animation */
#form-views.ng-enter {
-webkit-animation:slideInRight 2s both ease, fadeIn 1s both ease 2s;
-moz-animation:slideInRight 2s both ease, fadeIn 1s both ease 2s;
animation:slideInRight 2s both ease, fadeIn 1s both ease 2s;
}
/* leave animation */
#form-views.ng-leave {
-webkit-animation:slideOutLeft 2s both ease 1s, fadeOut 1s both ease;
-moz-animation:slideOutLeft 2s both ease 1s, fadeOut 1s both ease;
animation:slideOutLeft 2s both ease 1s, fadeOut 1s both ease;
}
and i think you know what the fadeIn and fadeOut animations should be.
UPDATE:
Here's a plunker with the code working the way I believe you want it to work. In chrome at least. You'll need to use the correct prefixes/no prefixes to get it working in other browsers.

Resources