Reputation: 1
I have a container as a header of a collapsible dropdown with a max-height of 30px. I'm toggling an ".open" class that changes the max-height to 30000px onClick in Javascript.
I'm trying to add a CSS transition to make this more fluid via transition: 1s; to the container class. The resulting effect is clunky and seems wrong: the div will collapse instantly (no ease-in/out) after a timeout equal to the 1s in the css element. I.e. if I add transition: 5s;, nothing will happen on the page until 5s, then the div will snap closed.
Hope this makes sense, thank you!
-- Sharing code for clarity:
html:
<section class="project">
<div class="project-head">
imgs/text with flexbox/grids etc
</div>
</section>
css:
section.project {
max-height: 30px;
overflow: hidden;
transition: all 0.5s ease-in-out;
}
.project-head {
display: grid;
height: 50px;
width: 95vw;
transition: .01s;
}
.open {
max-height: 100000px !important;
}
js:
document.querySelectorAll('.project-head').forEach(project => {
project.addEventListener('click', function () {
this.parentElement.classList.toggle("open");
});
})
Upvotes: 0
Views: 3871
Reputation: 36512
The code is doing what it has been asked to do - transitioning the max-height from something very big to something pretty small. It's only the last part of that that you will actually see and it looks instant because most of the transition time has been taken up with getting the huge max height down to the actual height of the div.
This snippet demonstrates a mitigation of the problem by putting the max-height to something that is not nearly so high. The outer div is set to have a different color on the smaller max height from the larger one so you can see what is happening:
document.querySelectorAll('.project-head').forEach(project => {
project.addEventListener('click', function() {
this.parentElement.classList.toggle("open");
});
})
section.project {
max-height: 30px;
overflow: hidden;
transition: all 5s ease-in-out;
background-color: rgba(255, 0, 0, 0.5);
}
.project-head {
display: grid;
height: 50px;
width: 95vw;
transition: .01s;
}
section.project.open {
max-height: 100px;
background-color: cyan;
}
<section class="project">
<div class="project-head">
imgs/text with flexbox/grids etc
</div>
</section>
Now try changing the max-height to something much larger and you will see it's transformation not being so noticable, because mostly it's off screen.
document.querySelectorAll('.project-head').forEach(project => {
project.addEventListener('click', function() {
this.parentElement.classList.toggle("open");
});
})
section.project {
max-height: 30px;
overflow: hidden;
transition: all 5s ease-in-out;
background-color: rgba(255, 0, 0, 0.5);
}
.project-head {
display: grid;
height: 50px;
width: 95vw;
transition: .01s;
}
section.project.open {
max-height: 10000px;
background-color: cyan;
}
<section class="project">
<div class="project-head">
imgs/text with flexbox/grids etc
</div>
</section>
The expansion seems to be much quicker, and the contraction much slower.
What to do in practice? As you rightly say you can't transition from/to auto so the max-height way is sort of a way round it. There seems to be no way other than choosing a sensible max height that is likely to be just more than the total height you want to expose. This is probably doable for an item in a menu as it will consist of a (very) few lines of text. However if you have lots of images this may be more difficult to judge. I suppose one way would be to get JS to calculate the heights at run time, but that then rather defeats the object of using the max height method.
Upvotes: 1