Greeting .
I already have the fade in animation.
When my dialog or box opens the animation is good.
However, the problem is that this does not happen when the animation is turned off at the click of the X button.
I want what happens now on fade in, happens on fade out too.
In short
when my dialog box pops up, animation pops up good
But I want to exit the dialog so that the animation is also scale down.
Code:
html
<div class="modal-dialog">
any content
// button which close animation
<button type="button" class="close" (click)="closeDialog()">
x
</button>
</div>
css
.modal.fade .modal-dialog {
animation-name: fade-in-scale-animation;
animation-duration: 0.3s;
}
#keyframes fade-in-scale-animation {
0% {transform: scale(0.5); opacity : 0 }
100% {transform: scale(1); opacity : 1}
}
EDIT:
Check this https://stackblitz.com/edit/angular-66n3nl
I want on close animation same as when a open?
You may apply a second class which has the animation, but dynamically.
const fadeInOutContainer = document.querySelector('#modal');
const fadeOut = () => {
fadeInOutContainer.classList.add('fade-out-container');
}
.fade-in-container {
background: black;
width: 200px;
height: 200px;
animation: fade-in 0.3s;
}
.fade-out-container {
animation: fade-out 0.3s;
}
#keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
#keyframes fade-out {
0% { opacity: 1; }
100% { opacity: 0; }
}
<div class="fade-in-container" id="modal">
<!-- Content here... -->
</div>
<button onclick="fadeOut()">Fade out</button>
This is just a sample for the sake of example. The idea is there, adding a new class to the container itself.
I suppose the modal will not be displayed once the animation ends, that's why I leave this with the class on it. If this is not the case and the HTML element will be recycled for some reason, you should remove the dynamic class later.
Edit on demand
If you define an HTML Element with a class, the styles whitin that class will be applied by the time the element is just rendered.
*.html
<div class="test">Just for the sake of example</div>
*.css
.test { border: 1px solid red; }
Here, the container above will have a red border by the time the page loads (or the container displays).
Talking about animations, if we have
.test {
border: 1px solid red;
animation: anim 1s;
}
#keyframes anim {
0% { opacity: 0 }
100% { opacity: 1 }
}
The animation anim will be triggered at the same time the styles whitin the test class are being applied.
That is why you can't apply fade-in-container and fade-out-container to the container in your HTML file.
What you want is to trigger the fade-in animation first (whenever the container is rendered), and that is why the container is defined with that class. However, you want the fade-out animation to trigger whenever you want, with an event. Like you said, it must trigger whenever the button Xis clicked.
So, you need to listen the click event of that button, then trigger the fade-out animation.
When the fade-out animation will be triggered? Whenever you apply the fade-out-container class to the container.
So, to summerize,
in the *.html
<div class="fade-in-container id="modal">
<!-- Only the fade-in-container class -->
</div>
<button id="btn">Fade out</button>
and the script should look like something like
*.js
const container = document.querySelector('#modal');
const btn = document.querySelector('#btn');
btn.addEventListener(() => {
// By adding the class, the animation will be triggered
container.classList.add('fade-out-container');
});
Hope it clarifies a bit.
Related
I have created animation using keyframes in css, how can re use that animation onclick?
I have to change background of the header on click, like carousel, and header must be animated on every click. But it is not working. I set header.style.animation to null and rewrite header.style.animation = 'animate-bg 1s linear' in each click, still not working
Let's add your animation to a class, you can trigger the animation just by removing and adding the class again.
This solution uses setTimout to be sure that the browser renders the deletion.
document.getElementById("header").addEventListener("click", function(e){
e.target.classList.remove("anim");
setTimeout(function(){
e.target.classList.add("anim");
});
})
#keyframes animate-bg {
0% {background-color: red;}
25% {background-color: yellow;}
50% {background-color: blue;}
100% {background-color: green;}
}
.anim {
animation: animate-bg 2s linear;
}
<div id="header">Hello Header</div>
Please add your code in your question first.
Add a class "active" onclick button then
button.active header{
animation: animate-bg 1s linear;
}
I have tried out the transitionend and animationend to change my css after a transition or keyframes animation ends. I made an example with both variants and they worked as expected: I can toggle a class, when a transition or animation ends. On hover, I start the transition/animation and in JavaScript I toggle a class, which changes the background-color, after the transition/animation changes.
The only difference is, that when I do the mouseout and the div goes back to the original state, with transition and transitionend, the class will be removed and the original background-color is visible. For keyframes animations and animationend, the class and background-color stay, also when I do the mouseout. How can I get the same behavoir for the animationend like the transition?
var boxTransition = document.getElementById("transition");
var boxAnimation = document.getElementById("animation");
/* add class after transition ends */
boxTransition.addEventListener("transitionend", changeBackground);
/* add class after keyframes animation ends */
boxAnimation.addEventListener("animationend", changeBackground);
function changeBackground() {
this.classList.toggle("box--end");
}
.box {
height: 100px;
margin-bottom: 30px;
width: 100px;
}
.box--transition {
background-color: lightcoral;
transition: width 0.5s ease-in-out;
}
.box--transition:hover {
width: 300px;
}
.box--animation {
background-color: lightblue;
}
.box--animation:hover {
animation: animateWidth 0.5s ease-in-out;
animation-fill-mode: forwards;
}
.box--end {
background-color: gray;
}
#keyframes animateWidth {
from {
width: 100px;
}
to {
width: 300px;
}
}
<div id="transition" class="box box--transition"></div>
<div id="animation" class="box box--animation"></div>
You should note that animation and transition are not the same, Thus event handling here is a bit trikcy.
I am going to explain what happens on both of them.
Transition: It's just the animating part of an element's changing property.
Example, it could be width or height or color. It is assigned on :hover usually.
Thus, it does not wait for animation if a user takes the mouse out of the element before the transition completes.
On the other hand,
Animation: is a complete set of transition and does not care about the user's mouseout event, once starts, it ends on it's own.
So, here is what you can do. As you assigned the toggle on transitionend it's okay because whenever the user takes the mouse out, transition completes and then the event triggers, but for animation, you should take care of them explicitly.
What I did is, (assuming user will keep the mouse on the element for a few second) added the class once animation has ended (like transitionend) then removed the class once the user takes the mouse out of the element.
Not exactly this is what you should do, but you can now get an idea on what to do and when.
Demo:
var boxTransition = document.getElementById("transition");
var boxAnimation = document.getElementById("animation");
/* add class after transition ends */
boxTransition.addEventListener("transitionend", changeBackground);
/* add class after keyframes animation ends */
boxAnimation.addEventListener("animationend", greyOnStart);
boxAnimation.addEventListener("mouseout", revertOnEnd);
function changeBackground() {
this.classList.toggle("box--end");
}
function greyOnStart(){
this.classList.add('box--end');
}
function revertOnEnd(){
this.classList.remove('box--end');
}
.box {
height: 100px;
margin-bottom: 30px;
width: 100px;
}
.box--transition {
background-color: lightcoral;
transition: width 0.5s ease-in-out;
}
.box--transition:hover {
width: 300px;
}
.box--animation {
background-color: lightblue;
}
.box--animation:hover {
animation: animateWidth 0.5s ease-in-out;
animation-fill-mode: forwards;
}
.box--end {
background-color: gray;
}
#keyframes animateWidth {
from {
width: 100px;
}
to {
width: 300px;
}
}
<div id="transition" class="box box--transition"></div>
<div id="animation" class="box box--animation"></div>
I can see 2 options for you.
First one is to call changeBackground on boxAnimation.onMouseOut():
boxAnimation.addEventListener("mouseout", changeBackground);
That will change background immediately.
Second is to set animation for .box--animation without hover:
#keyframes animateWidth2 {
from {
width: 300px;
}
to {
width: 100px;
}
}
.box--animation {
animation: animateWidth2 0.5s ease-in-out;
animation-fill-mode: forwards;
}
That will work like transition, but will happen on start too.
To prevent this happen from start you can add .box--hovered class to .box in changeBackground() and add animation to .box--animation.box--hovered instead of just .box--animation.
Example for second variant.
I have a page that has an input field and a "next" button. When the user clicks next, I want to shrink the input field and remove the "next" button. I have it mostly working as seen in this Bootply. My CSS animations look like this:
.default {
transition: all 1.0s ease;
}
.exit {
padding-left:5rem;
padding-right:5rem;
}
.remove-button {
animation: animate-remove-button 1.0s;
}
#keyframes animate-remove-button {
from {
transform:scaleX(1.0);
opacity: 1.0;
}
to {
transform:scaleX(0);
opacity: 0;
}
}
The animation runs. However, after the animation has completed, the button reappears. In addition, I basically want the width of the button to shrink all the way to 0 so that the text field grows. But, as you can see in the Bootply, that's not really happening, even though it kind of looks like it is.
What am I missing?
.remove-button {
animation: animate-remove-button 1.0s;
animation-fill-mode: forwards;
}
animation fill mode: forwards tell to keep the last state of animation.
Documentation: https://developer.mozilla.org/en/docs/Web/CSS/animation-fill-mode
On my website I have two links, if you click on portfolio, the div portfolio becomes visible.
I use this code to switch between them <a href="" onclick="return show('portfolio','profile');">
How can I make a quick fade-in-out between the divs using CSS?
Visit my site here and you'll see.
I've created a small demo for you to look at and have an idea of what AlexG is suggesting in Option 1 using CSS Animations (and jQuery).
JSFiddle
CODE SNIPPET:
var vHome = $("#home"),
vPortfolio = $("#portfolio"),
bTriggerHome = $("#trigger-home"),
bTriggerPortfolio = $("#trigger-portfolio");
function switchView() {
vHome.add(vPortfolio).toggleClass("hide-view");
};
bTriggerHome.add(bTriggerPortfolio).on("click", function() {
switchView();
});
#home,
#portfolio {
height: 500px;
animation: fadeInUp 1s both;
}
#home {
background-color: tomato;
}
#portfolio {
background-color: royalblue;
}
.hide-view {
display: none;
}
#keyframes fadeInUp {
0% {
opacity: 0;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0)
}
100% {
opacity: 1;
-webkit-transform: none;
transform: none
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="home">
<button id="trigger-portfolio">
Switch View
</button>
</div>
<div id="portfolio" class="hide-view">
<button id="trigger-home">
Switch View
</button>
</div>
You set your invisible divs to display: none. Thus, standard CSS transitions won't work out of the box.
display: none is a good idea because the browser won't spend time rendering that markup at all. However, CSS transitions need a hack to work with an element that move from display: none to display: !none, so you have two options:
1) Just use CSS Animations instead; add/remove a class to the elements that contain a CSS animation definition and it will play straight away.
2) Set your invisible divs to height: 0 and opacity: 0; and transition to opacity: 1 using a regular CSS transition (often triggered by a class change)
I have problem.
I want to instantly fade out my square (after clicking a button) then afterwards, fade it in slowly with a delayed time.
This is my example fiddle:
http://jsfiddle.net/qFYL7/6/
I changed the class but i'm afraid it's not the proper approach:
my_square.className = 'dim_fast';
my_square.className = 'square';
Thanks for any help given!
Well, in your function you're changing the class to dim_fast and then immediately back to square, which has no transitions :)
So, remove:
my_square.className = 'square';
Or at least append the 2nd class:
my_square.className = 'square dim_fast';
To fade out the square, and then fade in after an amount of time, you can use setTimeout.
Example
HOW ABOUT A PURE CSS3 SOLUTION?
First you need to make sure that the button is positioned before the square.
<button id="bt1"> </button>
<div id="my_square" class="square"> </div>
This is because CSS doesn't have a "previous sibling" selector.
Now you must use the :active pseudo-element on the button, to directly hide the square.
#bt1:active + .square
{
-webkit-transition:opacity 0s;
-moz-transition:opacity 0s;
-o-transition:opacity 0s;
transition:opacity 0s;
opacity:0;
}
When you click the button, the square will instantly be hidden.
Now add the transition on the square.
.square
{
-webkit-transition:opacity 2s;
-moz-transition:opacity 2s;
-o-transition:opacity 2s;
transition:opacity 2s;
opacity:1;
}
The Square will Fade In in 2 seconds.
CHECK IT OUT
I would use animation for this instead of transitions
Altered CSS (from your jsfiddle)
.square
{
width:100px;
height:100px;
background-color:blue;
opacity:1;
}
.fade{
animation: dim_fast_shine_slow 1s;
}
#keyframes dim_fast_shine_slow{
99%{opacity:0;}
100%{opacity:1}
}
Altered script
var my_square = document.getElementById('my_square');
function dim_fast_shine_slow()
{
// remove class
my_square.className = my_square.className.replace(' fade','');
setTimeout(function(){
// add class after 50 millisecons to allow the DOM to register the removal of the class
my_square.className += ' fade';
},50);
}
document.getElementById('bt1').onclick = dim_fast_shine_slow;
Demo at http://jsfiddle.net/gaby/qFYL7/7/
It's as simple as:
function dim_fast_shine_slow() {
my_square.classList.toggle("dim_fast");
}
In your version you had:
function dim_fast_shine_slow() {
my_square.className = 'dim_fast'; //changes class to dim_fast
my_square.className = 'square'; // changes it back to square
}
In each click the element's class name will just end up being "square".
It's 2018 and this solution works in edge, chrome, opera and firefox. Does'nt work in my IE11 though caniuse says IE11 has full keyframes support.
const fade = document.querySelector('.fade');
const cont = document.querySelector('.container');
document.body.addEventListener('click', ev => {
if (ev.target.classList.contains('fade')) {
cont.classList.add('fade-out-in');
}
});
cont.addEventListener('animationend', ev => {
cont.classList.remove('fade-out-in');
});
#keyframes fadeOutIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
.container {
width: 200px;
height: 200px;
margin-top: 10px;
background: red;
}
.fade-out-in {
animation: fadeOutIn 1s;
}
<button class="fade">Fade 1</button>
<button class="fade">Fade 2</button>
<button class="fade">Fade 3</button>
<div class="container"></div>
There should be a way of doing it without jQuery (which I am not aware of).. but in case u decide use jQuery :
$(my_square).hide("fast").show("slow");