Reputation: 9830
I'm trying to show an element for a second, then hide it. When a button gets clicked on, a class gets added, which has the opacity
and max-height
values. When that's finished animating, the class gets removed, and the element stays on screen for a second, due to the transition delay.
The problem is, when the buttons gets selected, the element doesn't go to its full height, unless:
transition
is changed from max-height 400ms ease, opacity 100ms ease
to all 400ms
JSFiddleelem.classList.remove('show');
is removed from the transition callback
. JSFiddleWhat am I doing wrong, and how can I fix it? (I need to have max-height
, and not height
.)
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
});
elem.addEventListener("transitionend", function() {
elem.classList.remove('show');
}, false);
#reference {
height: 100px;
background-color: lightblue;
font-size: 20px;
text-align: center;
}
#elem {
background-color: orange;
font-size: 20px;
text-align: center;
max-height: 0px;
opacity: 0;
transition: max-height 400ms ease, opacity 100ms ease;
transition-delay: 1000ms;
}
#elem.show {
opacity: 1;
max-height: 100px;
transition-delay: 0ms;
}
#inner-content {
padding: 20px;
}
<div id="reference">Height of 100px</div>
<button id="btn">Press Me</button>
<div id="elem">Should get a height of 100px
<div id="inner-content">Some Text</div>
</div>
Upvotes: 1
Views: 116
Reputation: 2304
To solve both the multiple clicks and the transition height problem you need to do a bit of a workaround. transitionend
actually fires four times. Twice for max height and twice for opacity. You need to track when the button is clicked and reset it after the fourth transition. The reason the height is not going to the full 100px is because you're removing the show
class right after the opacity transition and not the first max-height. You can see this if you put a console.log(e.propertyName)
in your transitionend event listener. This code works, but it is a bit ugly. I'm sure if you thought about it a bit there would be a better way to do it.
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
var hasClick = false;
var maxCount = 1;
btn.addEventListener('click', function() {
if(!hasClick) {
elem.classList.add('show');
hasClick = true;
}
});
elem.addEventListener("transitionend", function(e) {
console.log(e.propertyName);
if(e.propertyName=="max-height"){
elem.classList.remove('show');
if(maxCount>1){
hasClick = false;
maxCount = 0;
}
maxCount++
}
}, false);
#reference {
height: 100px;
background-color: lightblue;
font-size: 20px;
text-align: center;
}
#elem {
background-color: orange;
font-size: 20px;
text-align: center;
max-height: 0px;
opacity: 0;
transition: max-height 400ms ease, opacity 100ms ease;
transition-delay: 1000ms;
}
#elem.show {
opacity: 1;
max-height: 100px;
transition-delay: 0ms;
}
#inner-content {
padding: 20px;
}
<div id="reference">Height of 100px</div>
<button id="btn">Press Me</button>
<div id="elem">Should get a height of 100px
<div id="inner-content">Some Text</div>
</div>
Upvotes: 1
Reputation: 87191
2 things;
your transitionend
fires after 100ms, the opacity, hence the max-height has still 300ms left, which of course gets cancelled when you switch the class
the inner-content
is not big enough to occupy 100px height
So if you update your transitionend
function like this, it will work and wait for max-height
to fire
elem.addEventListener("transitionend", function(e) {
if (e.propertyName != 'opacity') {
elem.classList.remove('show');
}
}, false);
Stack snippet
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
});
elem.addEventListener("transitionend", function(e) {
if (e.propertyName != 'opacity') {
elem.classList.remove('show');
}
}, false);
#reference {
height: 100px;
background-color: lightblue;
font-size: 20px;
text-align: center;
}
#elem {
background-color: orange;
font-size: 20px;
text-align: center;
max-height: 0px;
opacity: 0;
transition: max-height 400ms ease, opacity 100ms ease;
transition-delay: 1000ms;
}
#elem.show {
opacity: 1;
max-height: 100px;
transition-delay: 0ms;
}
#inner-content {
padding: 40px;
}
<div id="reference">Height of 100px</div>
<button id="btn">Press Me</button>
<div id="elem">Should get a height of 100px
<div id="inner-content">Some Text</div>
</div>
Upvotes: 2
Reputation: 1348
Your transition runs too fast for the height to get completed. Try changing your transiton to----- transition: max-height 2s ease, opacity 1s ease;
Here is the screen video: https://www.screencast.com/t/Z1OFiQabl
Upvotes: 0