Adding a sliding animation in 2024 – WHY IS THIS SO HARD

A tower of blocks
Photo by Karl Abuid on Unsplash

I had a scenario for a personal project where I had e.g. a (+) button, and clicking that button should insert a new thingy into the DOM. No problem-o. button.addAdjacentHTML(element, <div>thingy</div>) to the rescue.

Okay, now do it, but with animations. Sure easy, peasy. Let me just animate opacity 0 -> 1 and… oh, that works for the new element, but the rest of the page just snaps to the new layout. That’s pretty jarring.

What if I just slide the new element into place? Surely that can’t be that hard….

7 hours later…

I tried many things, dear reader. I found some posts suggesting hacking with flex-grow with a flexbox. I tried more exotic things around negative margins, ScaleY, etc.

The answer I found which finally worked? display: grid. Yes, that weird style that makes sense but then you need something a little different and just use flex instead.

Anyways, click the link for the stackoverflow example. Otherwise here’s the code snippet that I made for my site:

  onNewComment(e: Event) {
    const addComment = this.shadowRoot!.querySelector('#add-comment');
    if (addComment == null) {
      return;
    }
    const commentHTML = `
  <div class="slide-down">
    <my-comment editable="true"></my-comment>
  </div>`;
    addComment.insertAdjacentHTML('afterend', commentHTML);
  }
}

and here’s the css:

@keyframes slideDown {
  from {
    grid-template-rows: 0fr;
  }

  to {
    grid-template-rows: 1fr;
  }
}

.slide-down {
  display: grid;
  animation: slideDown 1s forwards;
}

.slide-down > * {
  overflow: hidden;
}

P.S. If you want to use javascript, and you can figure out what height you want to do (fun exercise for the reader), you can just animate your height from 0 -> final height.px