AI CSS Animations

Message Queue Flow

Message blocks pop out of an isometric producer, step along a hairline queue bed in time and drop into the consumer, one tinted in the accent. SVG boxes with CSS translate and scale.

Also known as: message queue animation, event stream animation, hairline isometric.

HTML

<div class="hln-message-queue" role="img" aria-label="Messages moving through a queue">
  <svg viewBox="-110 -60 220 120" aria-hidden="true"><g transform="translate(0 6) scale(1.45)"><g><polygon points="-52,-18 -38,-11 -38,-25 -52,-32"/><polygon points="-22,-19 -38,-11 -38,-25 -22,-33"/><polygon points="-36,-40 -22,-33 -38,-25 -52,-32"/></g><line class="hln-message-queue-in" x1="-52" y1="-22.5" x2="-38" y2="-15.5"/><line class="hln-message-queue-in" x1="-52" y1="-27" x2="-38" y2="-20"/><g><polygon points="-36,-12 24,18 24,16 -36,-14"/><polygon points="36,12 24,18 24,16 36,10"/><polygon points="-24,-20 36,10 24,16 -36,-14"/></g><line class="hln-message-queue-in" x1="-30" y1="-17" x2="30" y2="13"/><g class="hln-message-queue-msg hln-message-queue-m0" style="animation-delay: 0s"><g class="hln-message-queue-pop"><g><polygon points="-3.5,-0.25 3.5,3.25 3.5,-3.75 -3.5,-7.25"/><polygon points="10.5,-0.25 3.5,3.25 3.5,-3.75 10.5,-7.25"/><polygon points="3.5,-10.75 10.5,-7.25 3.5,-3.75 -3.5,-7.25"/></g></g></g><g class="hln-message-queue-msg hln-message-queue-m1" style="animation-delay: -1.1s"><g class="hln-message-queue-pop"><g><polygon points="-3.5,-0.25 3.5,3.25 3.5,-3.75 -3.5,-7.25"/><polygon points="10.5,-0.25 3.5,3.25 3.5,-3.75 10.5,-7.25"/><polygon points="3.5,-10.75 10.5,-7.25 3.5,-3.75 -3.5,-7.25"/></g></g></g><g class="hln-message-queue-msg hln-message-queue-m2 hln-message-queue-hot" style="animation-delay: -2.2s"><g class="hln-message-queue-pop"><g><polygon points="-3.5,-0.25 3.5,3.25 3.5,-3.75 -3.5,-7.25"/><polygon points="10.5,-0.25 3.5,3.25 3.5,-3.75 10.5,-7.25"/><polygon points="3.5,-10.75 10.5,-7.25 3.5,-3.75 -3.5,-7.25"/></g></g></g><g class="hln-message-queue-msg hln-message-queue-m3" style="animation-delay: -3.3s"><g class="hln-message-queue-pop"><g><polygon points="-3.5,-0.25 3.5,3.25 3.5,-3.75 -3.5,-7.25"/><polygon points="10.5,-0.25 3.5,3.25 3.5,-3.75 10.5,-7.25"/><polygon points="3.5,-10.75 10.5,-7.25 3.5,-3.75 -3.5,-7.25"/></g></g></g><g class="hln-message-queue-msg hln-message-queue-m4" style="animation-delay: -4.4s"><g class="hln-message-queue-pop"><g><polygon points="-3.5,-0.25 3.5,3.25 3.5,-3.75 -3.5,-7.25"/><polygon points="10.5,-0.25 3.5,3.25 3.5,-3.75 10.5,-7.25"/><polygon points="3.5,-10.75 10.5,-7.25 3.5,-3.75 -3.5,-7.25"/></g></g></g><g><polygon points="22,19 36,26 36,12 22,5"/><polygon points="52,18 36,26 36,12 52,4"/><polygon points="38,-3 52,4 36,12 22,5"/></g><line class="hln-message-queue-in" x1="22" y1="14.5" x2="36" y2="21.5"/><line class="hln-message-queue-in" x1="22" y1="10" x2="36" y2="17"/></g></svg>
</div>

CSS

.hln-message-queue {
  --c: var(--hln-color, #ff4f2e);
  font-size: var(--hln-size, 16px);
  position: relative;
  display: grid;
  place-items: center;
  width: 22em;
  height: 12em;
  border-radius: 0.75em;
  background: #f6f5f1;
  overflow: hidden;
  --u: 1px;
}
.hln-message-queue svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-message-queue svg * {
  vector-effect: non-scaling-stroke;
}
.hln-message-queue .hln-message-queue-in {
  stroke: #9a9ca3;
}
.hln-message-queue .hln-message-queue-msg {
  translate: calc(-27.5 * var(--u)) calc(-13.75 * var(--u));
  animation: hln-message-queue-step 5.5s infinite;
}
.hln-message-queue .hln-message-queue-pop {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: inherit;
  animation-name: hln-message-queue-pop;
}
.hln-message-queue .hln-message-queue-hot polygon:last-child {
  fill: var(--c);
}
@keyframes hln-message-queue-step {
  0% { translate: calc(-27.5 * var(--u)) calc(-13.75 * var(--u)); }
  20% { translate: calc(-27.5 * var(--u)) calc(-13.75 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  24.95% { translate: calc(-11.03 * var(--u)) calc(-5.51 * var(--u)); animation-timing-function: ease-in-out; }
  27.2% { translate: calc(-12.55 * var(--u)) calc(-6.28 * var(--u)); animation-timing-function: ease-in-out; }
  29% { translate: calc(-12.25 * var(--u)) calc(-6.12 * var(--u)); }
  40% { translate: calc(-12.25 * var(--u)) calc(-6.12 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  44.95% { translate: calc(4.22 * var(--u)) calc(2.11 * var(--u)); animation-timing-function: ease-in-out; }
  47.2% { translate: calc(2.7 * var(--u)) calc(1.35 * var(--u)); animation-timing-function: ease-in-out; }
  49% { translate: calc(3 * var(--u)) calc(1.5 * var(--u)); }
  60% { translate: calc(3 * var(--u)) calc(1.5 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  64.95% { translate: calc(19.47 * var(--u)) calc(9.74 * var(--u)); animation-timing-function: ease-in-out; }
  67.2% { translate: calc(17.95 * var(--u)) calc(8.97 * var(--u)); animation-timing-function: ease-in-out; }
  69% { translate: calc(18.25 * var(--u)) calc(9.13 * var(--u)); }
  80% { translate: calc(18.25 * var(--u)) calc(9.13 * var(--u)); animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  84.95% { translate: calc(34.72 * var(--u)) calc(17.36 * var(--u)); animation-timing-function: ease-in-out; }
  87.2% { translate: calc(33.2 * var(--u)) calc(16.6 * var(--u)); animation-timing-function: ease-in-out; }
  89% { translate: calc(33.5 * var(--u)) calc(16.75 * var(--u)); }
  100% { translate: calc(33.5 * var(--u)) calc(16.75 * var(--u)); }
}
@keyframes hln-message-queue-pop {
  0% { scale: 0; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  8%, 100% { scale: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .hln-message-queue * {
    animation: none !important;
  }
  .hln-message-queue .hln-message-queue-m0 { translate: calc(-27.5 * var(--u)) calc(-13.75 * var(--u)); }
  .hln-message-queue .hln-message-queue-m1 { translate: calc(-12.25 * var(--u)) calc(-6.12 * var(--u)); }
  .hln-message-queue .hln-message-queue-m2 { translate: calc(3 * var(--u)) calc(1.5 * var(--u)); }
  .hln-message-queue .hln-message-queue-m3 { translate: calc(18.25 * var(--u)) calc(9.13 * var(--u)); }
  .hln-message-queue .hln-message-queue-m4 { translate: calc(33.5 * var(--u)) calc(16.75 * var(--u)); }
}

@media (prefers-reduced-motion: reduce) {
  .hln-message-queue, .hln-message-queue *, .hln-message-queue::before, .hln-message-queue::after, .hln-message-queue *::before, .hln-message-queue *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --hln-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hln-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar hairline animations