Home > Enterprise >  Want to increase the height of container div smoothly when an item is added to the list
Want to increase the height of container div smoothly when an item is added to the list

Time:10-16

I tried many times to do this but couldn't have done I must be missing something. So my problem is that I have a main div, it has a child div and the child div has an <ol>. I have a search box where I search something and a function which add the a particular result to the <ol> when I click on it. Initially the display of the main div is display:none; and height:auto;.

As soon as I click on the search result the display of main div becomes block using JS and add an li item to <ol>. The problem here is that the height of main div increases suddenly when the item is added to <ol>. Same thing happens when I want to delete an item from added items. but I want to increase and decrease it slowly.

You can checkout the sample code on codepen. link is https://codepen.io/sampat-28/pen/yLjwvEE

  <div >
  <div >
    <ol  id="added_list"></ol>
  </div>

</div>

this is the html layout and CSS is mentioned below . I am new to css animations so please forgive me if i have made some mistakes.

.search_results_container{
  display: none;
  border: 4px solid #FFF;
  margin: 40px auto 25px;
  box-sizing: border-box;
  border-radius: 21px;
  max-width: 850px;
  height:auto;
  width: auto;
}

.search_results{
 width:100%;
}

.added_list{
width:100%;
list-style-type:none;
height:auto;
height:100%;
}

Now there is a button on which if i click then it do two things If list is empty it makes display of .search_results_container to block and add a list item to it and this is the place where I am facing the problem. when I tried to add an animation to its height to increase slowly but it didn't worked. It increased the height equal to the list item's height immediately when i added a list item. but I want it to increase its height smoothly both the time adding an element and deleting an element from the list I need to use as order of items is important. Thank You.

CodePudding user response:

dose this work ?

const ol = document.querySelector('ol');

const button = document.querySelector('button');

button.addEventListener('click',()=>{
 const li = document.createElement('li');
 const text = document.createTextNode('carrort');
 li.appendChild(text);
 li.setAttribute('class', 'n')
 ol.appendChild(li);
})
ol li {
height:30px;
margin-bottom:2px;

}
ol li.n {
 animation: inc 600ms linear;
 transform-origin:top;
 }
 
 @keyframes inc {
  from {
    opacity:0;
    transform:scale(1,0) translateY(-10px);
  } to {
    opacity:1;
    transform:scale(1,1) translateY(0px)
  }
 }
<button>onAdd</button>
<ol>
 <li>carrort</li>
 <li>carrort</li>
 <li>carrort</li>
 <li>carrort</li>
 <li>carrort</li>
 <li>carrort</li>
</ol>

CodePudding user response:

If you want to make the height change smoothly, you should be changing the height in the js instead of display.

Just give a transition to your search_results_container and it should work.

note: transition don't work on display.

Now the question is how to change the height dynamically as the content inside the container is changing.

The answer:

element.children[0].clientHeight

it gives the height of the first child of the element.

Here is the modified codepen link:

https://codepen.io/Starnas/pen/Rwyddex?editors=1111

There some changes in the css and the js. HTMl is untouched.

A piece of advice: declare your variables on the top of the file and use them in your code instead of query selectors everywhere that makes the code much cleaner. If you still want to use the query selectors then make a function like:

function _(element){
   return document.querySelector(element);
}

//you can use it like this
_("#myDiv").style.height = "10px";

CodePudding user response:

I want it to increase its height smoothly both the time adding an element and deleting an element from the list I need to use as order of items is important.

As you asked, to smoothly changing the height of element when adding/removing an item. It can be done with the combination of CSS and JavaScript.

In your case, I used CSS animations to change the height of each item when it is added/removed.

.added_list > li{
  animation: pop-in 1s both;
}

@keyframes pop-in {
  0% {
    height: 0;
  }

  100% {
    height: 75px;
  }
}

When using element.remove() to removing an item from DOM it hides the element immediately and there none of the animation are transition works. So, to remove an item smoothly as you ask, you can do some animation like hiding the element before using the remove() method. So, using JavaScript I added a class of "delete" to give the hiding the animation and then removed from DOM.

CSS:

.added_list li.delete {
  animation: pop-out 1s both;
}

@keyframes pop-out {
  0% {
    height: 75px;
    opacity: 1;
  }
  100% {
    height: 0;
    opacity: 0;
  }
}

JavaScript:

function removeListItem(e) {
  let container = e.parentNode;
  
  // Adding a class to giving the deleting animation
  container.classList.add("delete")

  setTimeout(() => {
  
    // After a '1s' removing the item from list
    container.remove()

    // Hiding the container when the item <1 which is 0
    if (list.children.length < 1) {
      searchContainer.style.display = "none";
    }
  }, 1000)
}

After implementing this modifications your code may look like this:

let num = 0;
const searchContainer = document.querySelector(".search_results_container")
const list = document.querySelector("#added_list");

document.querySelector(".add_btn").addEventListener('click', function() {
  let cont_display = searchContainer.style.display;
  if (cont_display == "" || cont_display == "none") {
    searchContainer.style.display = "flex";
  }

  const newShow = document.createElement("li");
  newShow.classList.add("addanim");
  var attr = document.createAttribute('draggable');
  attr.value = 'true';
  newShow.setAttributeNode(attr);
  newShow.classList.add("added_item_container");
  newShow.innerHTML = `<p>Item ${num} </p><i  onclick="removeListItem(this)"></i>`
  num  ;
  list.prepend(newShow);
});

function removeListItem(e) {
  let container = e.parentNode;

  // Adding a class to giving the deleting animation
  container.classList.add("delete")

  setTimeout(() => {

    // After a '1s' removing the item from list
    container.remove()

    // Hiding the container when the item <1 which is 0
    if (list.children.length < 1) {
      searchContainer.style.display = "none";
    }
  }, 1000)
}
.search_results_container {
  display: none;
  border: 4px solid #FFF;
  margin: 40px auto 25px;
  box-sizing: border-box;
  border-radius: 21px;
  max-width: 500px;
  width: 100%;
  justify-content: center;
  height: auto;
  width: auto;
  background-color: #333;
}

.search_results {
  width: 100%;
}

.add_item_div {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

.add_btn {
  height: 42px;
  border: none;
  background-color: limegreen;
  color: #fff;
  font-size: 1.2rem;
  border-radius: 4px;
  cursor: pointer;
}

.added_list {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  box-sizing: border-box;
  padding: 0;
}

.added_list>li {
  display: flex;
  color: #fff;
  align-items: center;
  user-select: none;
  justify-content: space-evenly;
  font-size: 28px;
  animation: pop-in 1s both;
}


/* Animation to smoothly increase the container height while adding item */

@keyframes pop-in {
  0% {
    height: 0;
  }
  100% {
    height: 75px;
  }
}

.added_list li.delete {
  animation: pop-out 1s both;
}


/* Animation to smoothly decrease the container height and hide the item */

@keyframes pop-out {
  0% {
    height: 75px;
    opacity: 1;
  }
  100% {
    height: 0;
    opacity: 0;
  }
}

.added_list li p {
  margin: 0;
}

.fa-rectangle-xmark {
  cursor: pointer;
  transition: all 0.3s ease-in-out;
  color: #fff;
  text-rendering: auto;
  font-weight: 900;
  font-size: 28px;
  position: relative;
  float: right;
  background: #f80f0f;
  border-radius: 3px;
  width: 28px;
  height: 27px;
  text-align: center;
  right: 1px;
  margin-right: 10px;
}
<div >
  <div >
    <ol  id="added_list">
    </ol>
  </div>
</div>

<div >
  <button class='add_btn'>Add an item</button>
</div>

  • Related