Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to smoothly add dynamically created element to the DOM using CSS3 only?

My need is quite straightforward, yet I could not find a proper solution.

I create elements and add them to the DOM as a list of item, each new element is added before the old ones. I would like the new elements to be added "smoothly". The height of each elements is dynamic, so has to be the CSS rules.

I think I have to use CSS animations and keyframes, from what I read I can't use transitions because sometimes it is not rendered by the browser. I don't want to use Javascript, so I prefer to avoid solution with setTimeout() or jQuery. I'm sure this can be correctly done using modern CSS, but I still have to found the proper way to do so.

I have the begin of a solution (see below), but there is still max-height: 1000px hardcoded in the CSS, and I would like to avoid that, but I do not know how to because replacing it with auto or unset breaks the animation (see GIFs at the end of the post).

How would you implement a elegant transition for adding new elements to the DOM like this (not necessarily using the code I provided)?


Try the code on JSFiddle

    function addElement() {
        let dynamicHeight = Math.ceil(Math.random() * 30) + 100;
        let newElem = `<div class='elem' style='height: ${dynamicHeight}px'></div>`;
        let elements = document.getElementById("elements");
        elements.insertAdjacentHTML("afterbegin", newElem);
    }

    let button = document.getElementById("button")
    button.addEventListener("click", addElement);
    .elem {
      background-color: blue;
      margin: 5px;
      animation-duration:0.5s;
      animation-name: slidein;
    }
    
    
    @keyframes slidein {
      from {
        max-height: 0px;
        transform: scale(0);
        opacity: 0;
      }
    
      to {
        max-height: 1000px;
        transform: scale(1);
        opacity: 1;
      }
    }
    <button id="button">Add element</button>
    <div id="elements"></div>

With hardcoded max-height (looks nice): With hardcoded max-height

With unset max-height (looks clumsy): With unset max-height

like image 405
Delgan Avatar asked Jun 09 '18 17:06

Delgan


People also ask

How do you add dynamics to elements in CSS?

To do that, first we create a class and assign it to HTML elements on which we want to apply CSS property. We can use className and classList property in JavaScript. Approach: The className property used to add a class in JavaScript.

How do I create a dynamic DOM element?

New elements can be dynamically created in JavaScript with the help of createElement() method. The attributes of the created element can be set using the setAttribute() method.

How to change CSS of an element dynamically?

By calling element. style. color = "red"; you can apply the style change dynamically. Below is a function that turns an element's colour to red when you pass it the element's id .

How to add event handler to dynamically created button?

To attach event handlers to the dynamically created button, we need to select the button with a class of btn and add an event listener of click . We're saying that onclick of the button, the p tag with a class of moreInfo should display block .


1 Answers

Since you are defining a fixed height the solution is to animate the height from 0px to the fixed value. The trick here is to rely on CSS variable to be able to have a dynamic animation of the elements depending on their height:

function addElement() {
  let dynamicHeight = Math.ceil(Math.random() * 100) + 40;
  let newElem = `<div class='elem' style='--h: ${dynamicHeight}px'></div>`;
  let elements = document.getElementById("elements");
  elements.insertAdjacentHTML("afterbegin", newElem);
}

let button = document.getElementById("button")
button.addEventListener("click", addElement);
.elem {
  background-color: blue;
  margin: 5px;
  animation: slidein 0.5s forwards;
}

@keyframes slidein {
  from {
    height: 0px;
    transform: scale(0);
    opacity: 0;
  }
  to {
    height:var(--h); /*This will change for each element */
    transform: scale(1);
    opacity: 1;
  }
}
<button id="button">Add element</button>
<div id="elements"></div>
like image 99
Temani Afif Avatar answered Sep 24 '22 07:09

Temani Afif