I have an element which has display none on start. When i add a class to it i want it to fade in, using CSS.
I found this tutorial to use keyframes which is working nice
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>
You can't animate or transition the display property.
Note: That's not to say you can't use it in keyframe animation but that's not the same as actually animating it.
The reason why your Codepen demo doesn't work as intended is because the .active
class is being removed instantly so the animation out has no time to fire and the default display:none
is now applied immediately.
Since you are using Jquery anyway, there is a built in function fadeToggle
which will do what you want.
$('button').on('click', function(e) {
e.preventDefault();
$(this).siblings('.box').fadeToggle(500);
})
* {
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%;
display: none;
line-height: 100px;
background: #ccc;
border: 1px solid #444;
text-align: center;
}
<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>
</div>