CSS display none and opacity animation with keyframes not working
If you are using @keyframes
you should use -webkit-animation
instead of -webkit-transition
. Here is the doc for @keyframes
animation: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations.
See code snippet below:
.parent {
background-color: #000;
color: #fff;
width: 500px;
height: 500px;
padding: 5px;
}
.myDiv {
display: none;
opacity: 0;
padding: 5px;
color: #600;
background-color: #cec;
}
.parent:hover .myDiv {
display: block;
opacity: 1;
/* "both" tells the browser to use the above opacity
at the end of the animation (best practice) */
-webkit-animation: display-none-transition 1s both;
animation: display-none-transition 1s both;
}
@-webkit-keyframes display-none-transition {
0% {
opacity: 0;
}
}
@keyframes display-none-transition {
0% {
opacity: 0;
}
}
<div class="parent">
Hover on me...
<div class="myDiv">Hello!</div>
</div>
`display: none` not working in css animation?
Seems like the only way to achieve this is with JS, which is what vitilok posted in this comment:
Well, this is a bit tricky. So in order to accomplish what you want do the following: 1. remove display from will-change as well as from all frames. 2. add a new class .visuallyhidden { display: none; } 3. add: " setTimeout(function() { square.classList.add("visuallyhidden") }, 500) " inside the callback of click. You can see working example here And read this link if you want explanation
Basically, he put a setTimeout
statement which changed the display
property to none
after the animation time.
Their CSS
.visuallyhidden {
display: none;
}
Their JS
setTimeout(function() {
square.classList.add("visuallyhidden")
}, 500);
CSS animation keyframes with display none works to fade in, but not fade out
Trying to animate the display:none
is the root of your problem. The confusion for why the fade-in works and the fade-out doesn't comes from the combination of using both display
and opacity
.
The display
property is only being dictated by whether .active
is applied; the animations aren't actually changing it, whereas the opacity
is animated as expected. On the fade-in, this means that you immediately show your element, which then transitions from transparent to opaque. On the fade-out, this means that you immediately hide your element, which then transitions from opaque to transparent while hidden.
There are a couple different ways you could solve this, but it sort of depends on the context. For example, you could leave it as a block
element and use the height
property to make it collapse:
$('button').on('click', function(e) {
e.preventDefault();
$(this).siblings('.box').toggleClass('active');
})
@import "bourbon";
* {
box-sizing: border-box;
text-align: center;
}
button {
margin: 30px 0;
border: 1px solid #ccc;
text-align: center;
padding: 1em;
background: none;
box-shadow: none;
}
.box {
margin: 0 auto;
width: 80%;
height: 0;
display: block;
line-height: 100px;
background: #ccc;
border: 1px solid #444;
text-align: center;
opacity: 0;
animation: FadeOut 1s ease-in-out;
}
.box.active {
display: block;
height: initial;
opacity: 1;
animation: FadeIn 1s ease-in-out;
}
@keyframes FadeIn {
0% {
opacity: 0;
height: initial;
}
100% {
opacity: 1;
height: initial;
}
}
@keyframes FadeOut {
0% {
opacity: 1;
height: initial;
}
99% {
opacity: 0;
height: initial;
}
100% {
height: 0;
opacity: 0;
height: 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col">
<button class="toggle-good">Toggle display</button>
<p class="box good">I move nicely!</p>
<p>Extra paragraph to show collapse</p>
</div>
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.
Display none animation using keyframes
I don't think you can animate the display property from css alone.
Opacity and visibility can be animated however.
How about something like this:
.help-section {
animation: hidefromleft 2s;
}
@keyframes hidefromleft {
0% {right: 0; display: block; opacity: 1;}
50% {right: -300px; opacity: 0}
100% {opacity: 1; display: none;}
}
Personally, I always use transitions instead of animations (https://www.w3schools.com/css/css3_transitions.asp).
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 Keyframe animation not removing display block
You should not try animate between non numerical values.
Instead you can use opacity
and z-index
or left: -100%;
or things like that because you can't change display
to none
with keyframes.
You can read more about it here: Transitions and Animations in CSS- book
Related Topics
How to Save the Content in Uiwebview for Faster Loading on Next Launch
How to Indent Multiple Levels of Select Optgroup with CSS
Understanding Grid Negative Values
How to Insert Spaces/Tabs in Text Using HTML/Css
Making 'File' Input Element Mandatory (Required)
How to Make a 2 Column Layout Where Items Starts from Top to Bottom (Not Left to Right)
How to Increase Size of Serial Number in Ol
Target Safari CSS, But Not Chrome
Font Awesome Is Not Showing Icon
Internet Explorer 11 Word Wrap Is Not Working
Border with a Transparent Centred Arrow
How to Apply a Border Only Inside a Table
Horizontally and Vertically Center a Pre Tag Without the Use of Tables