CSS transition from `display: none` on class change?
It does work when you remove the display
properties.
#myelem {
opacity: 0;
transition: opacity 0.4s ease-in;
-ms-transition: opacity 0.4s ease-in;
-moz-transition: opacity 0.4s ease-in;
-webkit-transition: opacity 0.4s ease-in;
}
#myelem.show {
opacity: 1;
transition: opacity 0.4s ease-out;
-ms-transition: opacity 0.4s ease-out;
-moz-transition: opacity 0.4s ease-out;
-webkit-transition: opacity 0.4s ease-out;
}
JSFiddle.
The reason for this is that only CSS properties with numbers can be transitioned. What do you think the "50% state" should be between "display: none;
" and "display: block;
"? Since that can't be calculated, you can't animate the display
property.
Transitions on the CSS display property
You can concatenate two transitions or more, and visibility
is what comes handy this time.
div {
border: 1px solid #eee;
}
div > ul {
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
visibility: visible;
opacity: 1;
}
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
How do you transition between display:none and display:block?
If you use visibility
and opacity
in conjunction with max-height
, you can achieve a nice transition from visible to hidden or vice-versa. Setting the element's max-height
to 0
when it's hidden, and max-height
to Xpx
(larger than your element will ever be) when visible, prevents the element from messing with your layout in any way (as you mentioned in your question).
Here's a quick example:
var visible = document.querySelector(".visible");
function hide() {
visible.classList.add("hidden");
}
visible.addEventListener("click", hide);
div {
background-color: blue;
padding: 40px;
color: white;
cursor: pointer;
transition: all .1s ease;
}
.visible {
visibility: visible;
opacity: 1;
max-height: 1000px;
}
.hidden {
visibility: hidden;
opacity: 0;
max-height: 0;
}
<div class="visible">Click to hide</div>
Transition when removing class with display: none
Although "display: none" does not remove the element from the DOM, it does remove it from the page layout, so it cannot be animated. You can first remove the class with your "display: none" and then do the animation. Something like this:
$('#updater').click(function() {
$('#box7').removeClass('not-updated');
setTimeout(function() {
$('#box7').addClass('box-updated');
}, 0);
});
Your fiddle updated: https://jsfiddle.net/f2561ncf/
Css transition from display none to display block, navigation with subnav
As you know the display
property cannot be animated BUT just by having it in your CSS it overrides the visibility
and opacity
transitions.
The solution...just removed the display
properties.
nav.main ul ul {
position: absolute;
list-style: none;
opacity: 0;
visibility: hidden;
padding: 10px;
background-color: rgba(92, 91, 87, 0.9);
-webkit-transition: opacity 600ms, visibility 600ms;
transition: opacity 600ms, visibility 600ms;
}
nav.main ul li:hover ul {
visibility: visible;
opacity: 1;
}
<nav class="main">
<ul>
<li>
<a href="">Lorem</a>
<ul>
<li><a href="">Ipsum</a>
</li>
<li><a href="">Dolor</a>
</li>
<li><a href="">Sit</a>
</li>
<li><a href="">Amet</a>
</li>
</ul>
</li>
</ul>
</nav>
How can I animate my less from display: block to display: none ?
You cannot animate or transition from display: block;
to display: none;
, so you will need to remove this if you wish to animate it.
To ensure it fades and is removed you should animate the visibilty
and opacity
attributes.
Alternatively if you are using jQuery you can use the .fadeOut()
function.
MDN - CSS Visibility
jQuery - fadeOut()
CSS Opacity transition with display: none
As bizarre as it may seem, the answer is to add a line to your code as follows:
window.setTimeout((function () {
text.style.display = "flex";
document.body.offsetHeight; // Yes, this line!
text.style.opacity = "1";
}), 2000);
There's nothing special about this line other than that it performs a 'read' of data within your page (any operation that reads data from the DOM would work). What this does is force the browser to layout (or reflow) the page. This is important because, in general, if you carry out a series of 'write' operations - e.g. adding an element or setting it's style, the browser will batch these up and perform them all at once. This means that when you set the element's opacity to 0, and then to 1, the browser batches up these operations and carries them out together before reflowing the page, and thus there is no animation. By inserting a write operation in between, the browser is able to animate from the state of the element where it is transparent to the state where it is fully opaque.
Making it disappear is a little different:
text = document.getElementById("text");
window.setTimeout((function () {
text.style.display = "flex"; // write operation
document.body.offsetHeight; // read operation which forces reflow
text.addEventListener('transitionend', function listener1() {
text.removeEventListener('transitionend', listener1);
text.addEventListener('transitionend', function listener2() {
text.removeEventListener('transitionend', listener2);
text.style.display = 'none'; // remove text
});
window.setTimeout(function () {
text.style.opacity = 0.1; // hide text
}, 1000);
});
text.style.opacity = 1; // write operation - show text
}), 2000);
It's best to wait for the previous transition to complete before starting a new one. It's also good practise to remove the event listeners after the event has fired. You have to wait for the transition to complete before removing the element from the DOM. There is no need to carry out a read operation before setting the style that triggers an animation because the page has already been laid out with the opacity set to 1. I have set opacity to 0.1 so that you can see that the element actually disappears.
You can see a JFiddle here.
CSS Animation and Display None
CSS (or jQuery, for that matter) can't animate between display: none;
and display: block;
. Worse yet: it can't animate between height: 0
and height: auto
. So you need to hard code the height (if you can't hard code the values then you need to use javascript, but this is an entirely different question);
#main-image{
height: 0;
overflow: hidden;
background: red;
-prefix-animation: slide 1s ease 3.5s forwards;
}
@-prefix-keyframes slide {
from {height: 0;}
to {height: 300px;}
}
You mention that you're using Animate.css, which I'm not familiar with, so this is a vanilla CSS.
You can see a demo here: http://jsfiddle.net/duopixel/qD5XX/
play css animation with a display: none class
This is occurring for 3 reasons.
The animated style class was never removed when the see less button is clicked, prior to setting the display to none.
- Therefore, the elements hid, but on re-appearing, because they had the animated class, they re-animated at the same time.
When clicking the show more button, all of these will animate at once because when at the end of the page, the browser triggers a scroll event automatically, but the correct offset doesn't update in time.
- Therefore, the browser thinks all the elements have the same offset at the end of the page, so it animates them all
Jquery's scroll event listener stopped firing after reaching the end of the page. Not sure what caused it, but I know they sometimes implement their event listeners different than most browsers.
The fix:
- Replace jquery "scroll" event listener with native javascript/browser API scroll event listener
- Remove animated class whenever the see more or see less button is clicked.
- At the end of the day, we only want the animated class when a user scrolls
(All problems resided in javascript, css and html were fine)
Below is a quick fix version of your javascript code. However, I suggest doing some re-factoring of this version, to remove repeated code.
var doAnimations = function() {
var offset = $(window).scrollTop() + $(window).height(),
$animatables = $('.animatable');
if ($animatables.length == 0) {
$(window).off('scroll', doAnimations);
}
$animatables.each(function(i) {
$animatable = $(this);
if (($animatable.offset().top + $animatable.height() +65) < offset) {
$animatable.removeClass('animatable').addClass('animated');
}
});
};
function see_more(){
$animatables = $('.animated');
$animatables.each(function(i) {
var offset = $(window).scrollTop() + $(window).height(),
$animatable = $(this);
if (($animatable.offset().top + $animatable.height() +65) < offset) {
$animatable.removeClass('animated').addClass('animatable');
}
});
document.getElementById("hide").style.display = 'block';
document.getElementById("seeMore").style.display =`none`;
document.getElementById("seeLess").style.display =`block`;
$(window).on('scroll', doAnimations);
}
function see_less(){
$animatables = $('.animated');
$animatables.each(function(i) {
var offset = $(window).scrollTop() + $(window).height(),
$animatable = $(this);
if (($animatable.offset().top + $animatable.height() +65) < offset) {
$animatable.removeClass('animated').addClass('animatable');
}
});
document.getElementById("hide").style.display = 'none';
document.getElementById("seeMore").style.display =`block`;
document.getElementById("seeLess").style.display =`none`;
}
$(window).trigger('scroll');
window.addEventListener("scroll", doAnimations);
#seeLess{
display: none;
}
#hide{
display: none;
}
/* A N I M A T I O N */
.animatable {
/* initially hide animatable objects */
visibility: hidden;
/* initially pause animatable objects their animations */
-webkit-animation-play-state: paused;
-moz-animation-play-state: paused;
-ms-animation-play-state: paused;
-o-animation-play-state: paused;
animation-play-state: paused;
}
/* show objects being animated */
.animated {
visibility: visible;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-ms-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-play-state: running;
-moz-animation-play-state: running;
-ms-animation-play-state: running;
-o-animation-play-state: running;
animation-play-state: running;
}
@keyframes bounceIn {
0% {
opacity: 0;
transform: scale(.3);
}
50% {
transform: scale(1.05);
}
70% {
transform: scale(.9);
}
100% {
opacity: 1;
transform: scale(1);
}
}
.animated.bounceIn {
-webkit-animation-name: bounceIn;
-moz-animation-name: bounceIn;
-o-animation-name: bounceIn;
animation-name: bounceIn;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<div class="container-fluid"><button id="seeMore" onclick="see_more()">See all services</button></div>
<div id="hide">
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
<p class=" animatable bounceIn">Lion Cut</p>
<div class=" animatable bounceIn" style="margin-bottom: 300px;">
<p>This is one of our specialty Services, the Lion Cut. One of our customers favorite cuts,
have your favorite pet looking like a majestic king or queen in no time!
</p>
</div>
</div>
<div class="container-fluid"><button id="seeLess" onclick="see_less()">See less</button></div>
Related Topics
CSS Variables (Custom Properties) in Pseudo-Element "Content" Property
How to Make a Transparent Border with CSS
Make Second Div Appear Above First, Without Absolute Position or Changing HTML
CSS Font-Size Changes When Font-Family Falls Back
How to Prevent Division When Using Variables Separated by a Slash in CSS Property Values
Css: Full Size Background Image
How to Make a Fluid Sticky Footer
Responsive Bootstrap Designing in Cakephp 3X
Positioning a "Wrapper" Div Underneath a Fixed Navigation Bar
How to Check for Duplicate CSS Rules
How to Set a Flex-Container to Be the Width of Its Flex-Items
How to Center Variable Width Divs in CSS
How to Override the Minimum-Font-Size in Firefox
No Implicit Conversion of Nil into String
Customize a Select with Font-Awesome