简体   繁体   中英

How can I animate by expanding/collapsing a div when adding an element

I am making a To-do list where you can see the task's description when clicking on the task, basically I toggle the description's display from display: none; to display: block; , the problem is that when I make the description visible the parent div suddenly changes height and i want to animate it so that its smoother.

 const tasks = document.querySelectorAll('.task') tasks.forEach(x => { x.onclick = () => { x.querySelector('.description').classList.toggle('show') if (x.className == 'task flex') { x.className = 'task grid' } else { x.className = 'task flex' } } })
 * { font-family: poppins; margin: 0; padding: 0; box-sizing: border-box; } .project { background-color: teal; color: var(--white); display: grid; grid-template: 1fr 2fr / 1fr; border-radius: 10px; } .project * { display: flex; flex-direction: column; justify-content: center; width: 100%; height: 100%; } .project h3 { align-items: center; font-size: 1.5rem; font-weight: 500; margin-bottom: 1.5rem; color: #ffffff; } .tasks { align-items: flex-start; gap: 0.5rem; padding: 0 1rem 1rem; } .task { background-color: rgb(251, 238, 202); color: rgb(37, 36, 34); border-radius: 10px; } .flex { display: flex; flex-direction: row; align-items: center; padding: 0.5rem 0.5rem 0.5rem 0.75rem; } .grid { display: grid; grid-template: 1fr 1fr / 5fr 5fr 15px; grid-template-areas: none; padding: 0.5rem 0.5rem 0.5rem 0.75rem; grid-template-areas: 'task date del' 'desc desc desc'; } .title { font-size: 18px; line-height: 25px; grid-area: task; } .description { display: none; color: rgba(0, 0, 0, 0.6); font-size: 1rem; margin-left: 0.5rem; grid-area: desc; } .show { transform: scaleY(1); transition: transform 1s ease 0ms; display: block; } .date { color: var(--main-dark); font-style: italic; text-align: right; padding-right: 1rem; grid-area: date; }
 <div class="project"> <h3>Default project</h3> <div class="tasks"> <div class="task flex"> <p class="title">Water the plants</p> <p class="description">Tulips and Roses</p> <p class="date">18 Jun 2022</p> </div> <div class="task grid"> <p class="title">Feed the dog</p> <p class="description show">Chicken breast and bone</p> <p class="date">18 Jun 2022</p> </div> <div class="task flex"> <p class="title">Do the dishes</p> <p class="description">From lunch</p> <p class="date">18 Jun 2022</p> </div> </div> </div>

My standard for collapsing content vertically is the max-height property.

In theory, its pretty simple.

You have an element of max-height: 0px;and an active state of max-height: 300px; . Then you can add a transition like this: transition: max-height 0.5s ease; and it will work. However, there is a catch doing this with pure CSS.

EDIT// Remember to give your collapsing content a overflow: hidden;

Imagine your content is user submitted like in your case. The description could be 200px, 500px or even 0px of height.

In the case of your content being 300px, everything will work and animate like a charm because you perfectly hit the limit you defined.

In the case of your content being smaller, for example 200px, the animation will differ because it is still animating from 0px to 300px . Your content stops expanding at 200px so it will be faster than expanded than the 300px element. In fact, collapsing the element back to 0px will result in a delay of about 1/3 of your animation time because the element will stay at 200px until the transition has gone from 300px to 200px . Only then it will start collapsing.

Of course, there is always the option to just not bother and set the max-height to a reasonable default for your use-case.

As long as I've known AlpineJS , a minimal JS framework which is very easy to use, I didn't have to bother with this because the Collapse Plugin will do all the JS calculation for me so that the content is always transitioning perfectly. AlpineJS Collapse

If you don't want to use a JS Framework for this, there is a simple explanation on how to calculate the height of the element using JS, you can take a look at it here: W3Schools Collapsible

I can only reccommend taking a look at it or live with the consequences of the hard-coded default 300px or so.

Here is how I animate, where max-height is any hight that surpasses the max height of the element, if you have min height you can specify it too

#elementThatWillExpand
{
min-height:10px;
max-height:2000px;
transition:height 2s;
overflow:hidden;
}

So this should work, just change

.show {
  transform: scaleY(1);
  transition: transform 1s ease 0ms;
  display: block;
}

To

.show {
  display: block;
  max-height:3000px;
  transition:height 1s;
  overflow:hidden;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM