AI CSS Animations

Burger Stacking Loader

Bun, patty, lettuce and a sesame top bun drop in one by one and squash as they land, then the finished burger fades and it starts again. Fun for food, ordering and delivery apps.

Also known as: hamburger loading animation, burger css animation, food stacking loader.

HTML

<div class="ldr-burger" role="status" aria-label="Loading">
  <span class="ldr-burger-bun" style="--i: 0"></span>
  <span class="ldr-burger-patty" style="--i: 1"></span>
  <span class="ldr-burger-lettuce" style="--i: 2"></span>
  <span class="ldr-burger-top" style="--i: 3"></span>
</div>

CSS

.ldr-burger {
  --s: var(--ldr-size, 48px);
  --c: var(--ldr-color, #3b82f6);
  --light: color-mix(in srgb, var(--c) 35%, #fff);
  position: relative;
  width: var(--s);
  height: var(--s);
  animation: ldr-burger-serve 3s ease-in-out infinite;
}
.ldr-burger span {
  position: absolute;
  transform-origin: 50% 100%;
  animation: ldr-burger-drop 3s calc(var(--i) * 0.2s) infinite backwards;
}
.ldr-burger-bun {
  left: 14%;
  bottom: 14%;
  width: 72%;
  height: 14%;
  border-radius: calc(var(--s) / 30) calc(var(--s) / 30) calc(var(--s) / 8) calc(var(--s) / 8);
  background: var(--c);
}
.ldr-burger-patty {
  left: 9%;
  bottom: 30%;
  width: 82%;
  height: 13%;
  border-radius: var(--s);
  background: color-mix(in srgb, var(--c) 55%, #000);
}
.ldr-burger-lettuce {
  left: 7%;
  bottom: 43%;
  width: 86%;
  height: 8%;
  background:
    linear-gradient(var(--light) 0 0) 0 0 / 100% 50% no-repeat,
    radial-gradient(circle calc(var(--s) * 0.05) at 50% 50%, var(--light) 94%, transparent) 0 100% / calc(100% / 7) 100% repeat-x;
}
.ldr-burger-top {
  left: 14%;
  bottom: 51%;
  width: 72%;
  height: 28%;
  border-radius: 50% 50% calc(var(--s) / 30) calc(var(--s) / 30) / 90% 90% calc(var(--s) / 30) calc(var(--s) / 30);
  background:
    radial-gradient(circle calc(var(--s) * 0.028) at 30% 42%, var(--light) 90%, transparent),
    radial-gradient(circle calc(var(--s) * 0.028) at 52% 26%, var(--light) 90%, transparent),
    radial-gradient(circle calc(var(--s) * 0.028) at 70% 48%, var(--light) 90%, transparent),
    var(--c);
}
@keyframes ldr-burger-drop {
  0%     { transform: translateY(calc(var(--s) * -0.7)); opacity: 0; animation-timing-function: cubic-bezier(0.55, 0, 0.85, 0.35); }
  5%     { opacity: 1; }
  12%    { transform: translateY(0) scale(1, 1); }
  16%    { transform: translateY(0) scale(1.06, 0.78); }
  23%    { transform: translateY(0) scale(1, 1); opacity: 1; }
  76%    { transform: translateY(0); opacity: 1; }
  76.5%  { opacity: 0; }
  100%   { transform: translateY(calc(var(--s) * -0.7)); opacity: 0; }
}
@keyframes ldr-burger-serve {
  0%, 65%   { opacity: 1; transform: translateY(0); }
  75%, 100% { opacity: 0; transform: translateY(calc(var(--s) * -0.08)); }
}

@media (prefers-reduced-motion: reduce) {
  .ldr-burger, .ldr-burger *, .ldr-burger::before, .ldr-burger::after, .ldr-burger *::before, .ldr-burger *::after {
    animation-duration: 3s;
  }
}

Customizing this loader

  • Color: set --ldr-color on the element or a parent. Currently previewing #3b82f6.
  • Size: set --ldr-size. Every dimension in the snippet is derived from it. Currently previewing 64px.
  • Speed: change the duration on the animation shorthand. Delays on the children are relative, so they keep their rhythm.
  • Accessibility: the root carries role="status" and an aria-label so screen readers announce the wait. The reduced-motion rule at the end slows the animation for users who asked for less motion.

Similar loaders