I have set animations on ng-view to fade for 1 second, but it doesn't let the animation out be finished:
.fadethis {
&.ng-enter, &.ng-leave {
-webkit-transition: all linear 1s;
-moz-transition: all linear 1s;
transition: all linear 1s;
display: block !important;
}
&.ng-enter, &.ng-leave.ng-leave-active {
opacity:0;
}
&.ng-leave, &.ng-enter.ng-enter-active {
opacity:1;
}
}
can't I make angular-animate finish the 1 second animation first?
DEMO: http://jsfiddle.net/bnyJ6/79/
It does not look like your view is actually fading out in your example. If it did, the page you are navigating to would appear and begin fading in before the previous page had finished fading out.
Currently I believe the easiest way to simulate the animations waiting for each other is to add a transition-delay to the enter animation (source).
This can get messy though. In your example the page you are navigating to would still begin to take up space before fading in and bump down the page that is fading out. You can get around this by setting your view to position: absolute;.
Demo without transition-delay: http://jsfiddle.net/5evFx/
Demo with transition-delay and position: absolute: http://jsfiddle.net/spKnX/
Working markup:
<div ng-view class="view fadein fadeout"></div>
Working CSS:
.fadein.ng-enter,
.fadeout.ng-leave {
-webkit-transition: all linear 1s;
-moz-transition: all linear 1s;
-o-transition: all linear 1s;
transition: all linear 1s;
display: block !important;
}
.fadein.ng-enter {
opacity: 0;
}
.fadeout.ng-leave {
opacity: 1;
}
.fadein.ng-enter.ng-enter-active {
transition-delay: 1s;
opacity: 1;
}
.fadeout.ng-leave-active {
opacity: 0;
}
html, body, .container {
height: 100%;
}
.view {
position: absolute;
}
Related
So I have got an animation on an object (<div>).
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
This animation obviously happens when the object is being created. What I need now is an animation or transition that shrinks my object back down to max-height: 0px;.
Giving the property max-height an transition and then changing the value of it in js to 0px does nothing.
Also creating a reversed animation and then repolacing the original
object with a clone and this animation does not bring the object down
to 0px.
(Please keep in mind that I am not intersted in changing the scale or other transform properties)
Thanks for your suggestions!
More details:
My <div> object:
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
}
.law-list .law-item {
-webkit-transition: max-height .9s linear;
-moz-transition: max-height .9s linear;
-ms-transition: max-height .9s linear;
-o-transition: max-height .9s linear;
transition: max-height .9s linear;
}
.fade-in {
-webkit-animation-duration: .9s;
animation-duration: .9s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-in-left;
animation-name: fade-in-left;
}
I create my html content in js and the html elements looks like this:
<div class='law-item fade-in' id='law_0'>Law Nr.1</div>
<div class='law-item fade-in' id='law_1'>Law Nr.2</div>
So when an element is created, the max-height animation plays.
When I want to delete an object, I want the situation stated above to occur: a fade out animation and then an deletion.
I handel his in a js function:
function removeLaw(id) {
document.getElementById("law_" + id).style.maxHeight = "0px";
setTimeout(function() {
document.getElementById("law_" + id).parentElement.removeChild(document.getElementById("law_" + id));
}, 900);
}
As stated it should fade out to 0 max-height. But all it does it stay at the current max-height and then after max-height get deleted.
There is always more than one way to do something. Since you are using an animation to set the height, it is best to use an animation to remove the height as well. Think of the animation ending at 100%. At this point, your max-height is set. Even though you have a transition set on the element, the animation is preventing the transition from firing as it should. The animation event is still firing even though it is at 100%. You could set an event listener on the animationend event from the beginning and pause the animation. I haven't tried this, but it may work.
What I found in your case is to create a fade-out class and a fade-out animation. I removed all references to transition from your css since I used animations. I suppose you could go the other way and use only transitions instead of animations, but mixing them is the problem you have been having.
I created a basic click event listener on each law-item and changed the class on the item prior to removing when the new animation ended.
function removeLaw(id) {
var el = document.getElementById(id);
el.classList.remove('fade-in');
el.classList.add('fade-out');
el.addEventListener('animationend', function(e) {
el.remove();
})
}
var lawItems = document.querySelectorAll('.law-item');
lawItems.forEach(function(lawItem){
this.addEventListener('click', function(e) {
removeLaw(e.target.id)
})
})
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
}
#keyframes fade-out-left {
0% {
max-height: 200px;
}
100% {
max-height: 0px;
}
}
.law-list .law-item {
height: 200px;
}
.fade-in {
-webkit-animation-duration: 900ms;
animation-duration: 900ms;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-in-left;
animation-name: fade-in-left;
}
.fade-out {
-webkit-animation-duration: 900ms;
animation-duration: 900ms;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-out-left;
animation-name: fade-out-left;
}
<div class='law-list'>
<div class='law-item fade-in' id='law_0'>Law Nr.1</div>
<div class='law-item fade-in' id='law_1'>Law Nr.2</div>
</div>
I am working on a new site that is using page transitions. The old content fades away and the new content fades in - at least that's what should happen.
When the new content is loaded, I use JS to set it's opacity: 0
this.newContainer.style.opacity = 0;
Then, I add a new class so I can use CSS transitions
this.newContainer.classList.add("animate-in");
This is the CSS for the .animate-in
.wrapper.animate-in {
opacity: 1;
visibility: visible;
-webkit-transition: all 1000ms ease-in-out;
-moz-transition: all 1000ms ease-in-out;
-ms-transition: all 1000ms ease-in-out;
-o-transition: all 1000ms ease-in-out;
transition: all 1000ms ease-in-out;
}
However, this doesn't work. The code doesn't animate the opacity from 0 to 1. Instead, it is animating backwards, from 1 to 0. It seems like the classList.add doesn't hear the previous line of code.
Anyone know how to fix this?
EDIT
OK, so I learned that using the JS style.opacity will completely override any opacity CSS rules. This is my problem. How do I get around this?
Try to use css animation and remove code--> this.newContainer.style.opacity = 0;
.wrapper.animate-in {
opacity: 1;
transition: all 1000ms ease-in-out;
animation: animate-in01 1s;
animation-iteration-count: 1;
}
#keyframes animate-in01{
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
I have a pagination that i want to change the content of container by click on it.
it works, but i want that it happen smoothly.
<div id='container>
<div id='0' class='box'></div>
<div id='1' class='box'></div>
<div id='2' class='box'></div>
</div>
style :
#container{'
position:relative
}
.box{
position: absolute;
display: none;
}
.box:first-child{
display: inline-block;
}
by click on my pagination buttons :
$(function () {
var obj = $('#pagination').twbsPagination({
totalPages: 3,
visiblePages: 2,
prev:'Prev',
next:'Next',
onPageClick: function (event, page) {
console.info(page);
page=page-1;
$(".box").hide(function () {
$("#"+page).show();
});
}
});
how can i do this smoothly?
You have 2 options
In Jquery Way:-
Use fadeIn fadeOut in place of show hide
$(".box").fadeOut("slow",function () {
$("#"+page).fadeIn('slow');
});
In CSS Way:-
Use transition to animate. but in this case you only can play smoothly with opacity and visibility and not display
.box{
position: absolute;
opacity: 0;
visibility:hidden;
-webkit-transition: all 2s ease 0s;
-moz-transition: all 2s ease 0s;
-o-transition: all 2s ease 0s;
-ms-transition: all 2s ease 0s;*/
transition: all 2s ease 0s;
}
You can use transitions with opacity rather than hiding an showing the elements.
.box {
position: absolute;
display: block; // not required but do not keep it as display: none
opacity: 0; // make the div invisible!
transition: opacity 1s linear; // tell the browser how and what to transition
-webkit-transition: opacity 1s linear; // webkit support
-moz-transition: opacity 1s linear; // firefox support
}
.box.active {
opacity: 1; // only applies when a box has the class .box and .active
}
Instead of calling .show() to show the element you can add and remove the active class on each div.
I have this element which already has an animation that fires at some time:
.box {
width: 100%;
height: 87.5%;
background: #DDD;
position: absolute;
top: 12.5%;
left: 0%;
-webkit-animation: load 0.5s ease-out 5s backwards;
animation: load 0.5s ease-out 5s backwards;
}
But at some time, always after that animation has finished I want to fire a new animation on the same element. So I thought that creating a new class and attaching it to the element with JS would work:
.unload{
-webkit-animation: unload 0.5s ease-out 0.5s backwards !important;
animation: unload 0.5s ease-out 0.5s backwards !important;
}
document.querySelector(".box").classList.add('unload');
But it doesn't work. The class gets added but the animation doesn't happen.
Does anyone know why this is happening and how to fix it?
The keyframe's names were slightly different and didn't fit the call. Sorry, it was quite stupid...
Six years down the line and I had the same problem, which somehow I was able to figure out. I might as well just share it.
What helped me was specificity. Instead of applying the modifier class directly to the animated element I applied it to the parent div and used the descendant selector like this:
HTML
<div class="container container--unload"> //this second class can be added later with JS
<div class="box">
//some feature here
</div>
</div>
CSS
.box {
width: 100%;
height: 87.5%;
background: #DDD;
position: absolute;
top: 12.5%;
left: 0%;
animation: load 0.5s ease-out 5s backwards;
}
.container--unload .box{
animation: unload 0.5s ease-out 0.5s backwards;
}
JS
document.querySelector(".container").classList.add("container--unload");
Tested and seems to be working. I left out the keyframes.
Cheers!
Is there a way to animate display:none to display:block using CSS so that the hidden div slides down instead of abruptly appearing, or should I go about this a different way?
$(document).ready(function() {
$('#box').click(function() {
$(this).find(".hidden").toggleClass('open');
});
});
#box {
height:auto;
background:#000;
color:#fff;
cursor:pointer;
}
.hidden {
height:200px;
display:none;
}
.hidden.open {
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="box">
Initial Content
<div class="hidden">
This is hidden content
</div>
</div>
And a JSFiddle
Yes, there is a way:
http://jsfiddle.net/6C42Q/12/
By using CSS3 transitions, and manipulate height, rather than display property:
.hidden {
height: 0px;
-webkit-transition: height 0.5s linear;
-moz-transition: height 0.5s linear;
-ms-transition: height 0.5s linear;
-o-transition: height 0.5s linear;
transition: height 0.5s linear;
}
.hidden.open {
height: 200px;
-webkit-transition: height 0.5s linear;
-moz-transition: height 0.5s linear;
-ms-transition: height 0.5s linear;
-o-transition: height 0.5s linear;
transition: height 0.5s linear;
}
More here: Slide down div on click Pure CSS?
Since you're already using jQuery, the simplest thing is just to use slideDown(). http://api.jquery.com/slidedown/
There's also slideToggle().
Then you don't need to manually do all the browser-specific transition css.
I like the idea of CSS transitions, but it's still very jumpy. Sometimes the max-height has to be set to a very high number because of dynamic content which renders the transition useless as it's very jumpy. So, I went back to jQuery, but it had its own faults. inline elements are jumpy.
I found this to work for me:
$(this).find('.p').stop().css('display','block').hide().slideDown();
The stop stops all previous transitions.
The css makes sure it's treated as a block element even if it's not.
The hide hides that element, but jquery will remember it as a block element.
and finally the slideDown shows the element by sliding it down.
What about
$("#yourdiv").animate({height: 'toggle'});
Toggle will switch your div on/off, and the animate should make it appear from below. In this scenario, you don't need the specific CSS to "hide" it.
We can use visibility: hidden to visibility: visible instead of display: none to display: block property.
See this example:
function toggleSlide () {
const div = document.querySelector('div')
if (div.classList.contains('open')) {
div.classList.remove('open')
} else {
div.classList.add('open')
}
}
div {
visibility: hidden;
transition: visibility .5s, max-height .5s;
max-height: 0;
overflow: hidden;
/* additional style */
background: grey;
color: white;
padding: 0px 12px;
margin-bottom: 8px;
}
div.open {
visibility: visible;
/* Set max-height to something bigger than the box could ever be */
max-height: 100px;
}
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
<button
onclick="toggleSlide()"
>
toggle slide
</button>
I did this workaround for the navigation header in my React site.
This is the regular visible css class
.article-header {
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
}
This is the class that is attached to the div (when scrolled in my case)
.hidden {
top: -50px !important;
transition: top 0.5s ease-in-out;
}
You can use also
$('#youDiv').slideDown('fast');
or you can tell that the active div goes up then the called one goes down
$('.yourclick').click(function(e) {
var gett = $(this).(ID);
$('.youractiveDiv').slideUp('fast', function(){
$('.'+gett).slideDown(300);
});
});
Something like that.