AI CSS Animations

Database Sync

Two isometric database cylinders trade one accent packet along a floor line, and each lid pulses as the write lands. Hairline SVG with CSS translate, scale and opacity.

Also known as: database replication animation, hairline isometric, data sync icon.

HTML

<div class="hln-database-sync" role="img" aria-label="Two databases syncing a record back and forth">
  <svg viewBox="-110 -60 220 120" aria-hidden="true"><g transform="translate(0 15) scale(1.3)"><g><path d="M-50.97 -41V-17A16.97 8.49 0 0 0 -17.03 -17V-41Z"/><path class="hln-database-sync-in" fill="none" d="M-50.97 -25A16.97 8.49 0 0 0 -17.03 -25"/><path class="hln-database-sync-in" fill="none" d="M-50.97 -33A16.97 8.49 0 0 0 -17.03 -33"/><ellipse cx="-34" cy="-41" rx="16.97" ry="8.49"/></g><g class="hln-database-sync-ring hln-database-sync-ring-a"><ellipse cx="-34" cy="-41" rx="16.97" ry="8.49"/></g><line class="hln-database-sync-in" x1="-22" y1="-11" x2="22" y2="11"/><g class="hln-database-sync-move"><g class="hln-database-sync-pkt"><g><polygon points="-5,0 0,2.5 0,-2.5 -5,-5"/><polygon points="5,0 0,2.5 0,-2.5 5,-5"/><polygon points="0,-7.5 5,-5 0,-2.5 -5,-5"/></g></g></g><g><path d="M17.03 -7V17A16.97 8.49 0 0 0 50.97 17V-7Z"/><path class="hln-database-sync-in" fill="none" d="M17.03 9A16.97 8.49 0 0 0 50.97 9"/><path class="hln-database-sync-in" fill="none" d="M17.03 1A16.97 8.49 0 0 0 50.97 1"/><ellipse cx="34" cy="-7" rx="16.97" ry="8.49"/></g><g class="hln-database-sync-ring hln-database-sync-ring-b"><ellipse cx="34" cy="-7" rx="16.97" ry="8.49"/></g></g></svg>
</div>

CSS

.hln-database-sync {
  --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-database-sync svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-database-sync svg * {
  vector-effect: non-scaling-stroke;
}
.hln-database-sync .hln-database-sync-in {
  stroke: #9a9ca3;
}
.hln-database-sync .hln-database-sync-move {
  translate: calc(-19.5 * var(--u)) calc(-9.75 * var(--u));
  animation: hln-database-sync-move 6s infinite;
}
.hln-database-sync .hln-database-sync-pkt {
  transform-box: fill-box;
  transform-origin: 50% 80%;
  animation: hln-database-sync-pkt 6s infinite;
}
.hln-database-sync .hln-database-sync-pkt polygon {
  fill: var(--c);
}
.hln-database-sync .hln-database-sync-ring {
  fill: none;
  stroke: var(--c);
  opacity: 0;
  transform-box: fill-box;
  transform-origin: 50% 50%;
}
.hln-database-sync .hln-database-sync-ring-b {
  animation: hln-database-sync-ring 6s infinite;
}
.hln-database-sync .hln-database-sync-ring-a {
  animation: hln-database-sync-ring 6s 3s infinite;
}
@keyframes hln-database-sync-move {
  0%, 8% { translate: calc(-19.5 * var(--u)) calc(-9.75 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  30%, 58% { translate: calc(19.5 * var(--u)) calc(9.75 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  80%, 100% { translate: calc(-19.5 * var(--u)) calc(-9.75 * var(--u)); }
}
@keyframes hln-database-sync-pkt {
  0% { scale: 0; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  8%, 28% { scale: 1; animation-timing-function: ease-in; }
  33%, 50% { scale: 0; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  58%, 78% { scale: 1; animation-timing-function: ease-in; }
  83%, 100% { scale: 0; }
}
@keyframes hln-database-sync-ring {
  0%, 30% { opacity: 0; scale: 1; }
  31% { opacity: 1; scale: 1; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
  46%, 100% { opacity: 0; scale: 1.5; }
}
@media (prefers-reduced-motion: reduce) {
  .hln-database-sync * {
    animation: none !important;
  }
  .hln-database-sync .hln-database-sync-move { translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hln-database-sync, .hln-database-sync *, .hln-database-sync::before, .hln-database-sync::after, .hln-database-sync *::before, .hln-database-sync *::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