Card Slide UI

by sperske

HTML

<div id="container"></div>
<button>swap</button>

CSS

body {
  padding: 2em;
}

#container {
  border: 1px solid grey;
  padding-inline: 1em;
  display: grid;
  overflow: hidden;
}

#container > div {
  grid-row: 1;
  grid-column: 1;
  border: 1px solid grey;
  padding: 1em;
  align-self: start;
  border-radius: 1em;
  background-color: #fff;
}
/* Animation from https://webcode.tools/css-generator/keyframe-animation */
@keyframes fade-in {
  0% {
    transform: translateY(-100%);
  }

  100% {
    transform: translateY(0);
  }
}
@keyframes fade-out {
  0% {
    opacity: 1;
    transform: translateY(0);
  }

  100% {
    opacity: 0;
    transform: translateY(-100%);
  }
}
.exiting {
  animation: fade-out 0.3s ease 0s 1 normal forwards;
}
.entering {
  animation: fade-in 0.3s ease 0s 1 normal forwards;
}

JavaScript

function create(id, innerHTML) {
  const el = document.createElement("div")
  el.setAttribute("id", id)
  el.innerHTML = innerHTML
  return el
}

function replace(el, container, duration) {
  const current = container.children[0]
  current.classList.add("exiting")
  el.classList.add("entering")
  container.appendChild(el)
  setTimeout(() => {
    el.classList.remove("entering")
    current.classList.remove("exiting")
    container.replaceChildren(el)
  }, duration)
}

const large = create(
  "large",
  `Large UI
  <br/>
  There is a lot of content here so one is larger than te other
    <br/>
  There is a lot of content here so one is larger than te other
    <br/>
  There is a lot of content here so one is larger than te other
    <br/>
  There is a lot of content here so one is larger than te other`,
)
const small = create("small", `Small UI`)
const container = document.getElementById("container")
container.replaceChildren(large)
let isLarge = true
let isAnimating = false
const ANIMATION_MS = 300
const action = document.getElementsByTagName("button")[0]

action.addEventListener("click", () => {
  if (isAnimating) return

  setTimeout(() => {
    isAnimating = false
  }, ANIMATION_MS)

  isAnimating = true
  if (isLarge) {
    replace(small, container, ANIMATION_MS)
  } else {
    replace(large, container, ANIMATION_MS)
  }
  isLarge = !isLarge
})