I'm trying to create a custom drop down menu in ReactJs. When a user clicks the heading, a list of items appears below it. This works but I want the div that contains both the heading and the list (.db-container
) to in increase its height depending on if the list (.db-list
) is visible or not. I can use display:none
/block
or position:absolute
/relative
with transform:scaleY(0)
/scaleY(1)
on .db-list
but then I cannot animate it or use transitions. I've tried using visibility:hidden
/visible
which does hide the list but the container remains its full size.
I am using ReactJs and in the code snippet below, the handleClick()
function just changes isVisible
from true to false and vice versa.
.db-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.db-list {
transform: scaleY(0);
transform-origin: top center;
position: absolute;
}
.visible-true {
transform: scaleY(1) !important;
position: relative !important;
}
<div className='db-container'>
<h3 className='db-name' onClick={handleClick}>Headinf</h3>
<ul className={`db-list visible-${isVisible}`}>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
Is there a way to get .db-container
to change its height depending on the visibility of .db-list
and use animations or transitions?
CodePudding user response:
Use max-height and overflow:hidden. These are animatable. Needs a bit of tidying up but you'll get the general idea. Setting max-height means the element will just size itself to the content as long as you set it to a high enough value. (I've made it transform on :hover but you can change it to a click in react)
.db-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.db-list {
max-height:0px;
overflow: hidden;
transition: max-height 1s;
}
.db-name:hover .db-list {
max-height:1000px;
}
CodePudding user response:
Instead of shrinking, you can use position:absolute
then delay your component from re-rendering when hiding for a few millisecond then animate.
I got this problem when I built a custom drawer menu. However, when I hide the component it doesn't animate because you can't animate what you can't see. So I had to delay the component re-render then set right
to a negative number to move it out of the view port visible part with animation. After that hide the component.
If you use height(to hide by shrinking); it works, but for a second you will see the component children get misplace and it doesn't look great.