AI CSS Animations

CI Pipeline Stages

Build, test and deploy blocks lift in turn on a hairline rail, each lit by the accent while it runs and checked off when it passes. Isometric SVG boxes with CSS keyframes.

Also known as: ci cd pipeline animation, build pipeline animation, hairline isometric.

HTML

<div class="hln-ci-pipeline" role="img" aria-label="Build, test and deploy stages running in turn">
  <svg viewBox="-110 -60 220 120" aria-hidden="true"><g transform="translate(0 4) scale(1.6)"><line class="hln-ci-pipeline-in" x1="-18" y1="-9" x2="-8" y2="-4"/><line class="hln-ci-pipeline-in" x1="6" y1="3" x2="16" y2="8"/><circle class="hln-ci-pipeline-dot" cx="-18" cy="-9" r="1.5"/><circle class="hln-ci-pipeline-dot hln-ci-pipeline-d1" cx="6" cy="3" r="1.5"/><g class="hln-ci-pipeline-b0"><g><polygon points="-39,-12.5 -25,-5.5 -25,-13.5 -39,-20.5"/><polygon points="-11,-12.5 -25,-5.5 -25,-13.5 -11,-20.5"/><polygon points="-25,-27.5 -11,-20.5 -25,-13.5 -39,-20.5"/></g><polygon class="hln-ci-pipeline-in" points="-25,-24.5 -17,-20.5 -25,-16.5 -33,-20.5"/><polygon class="hln-ci-pipeline-lamp" points="-25,-24.5 -17,-20.5 -25,-16.5 -33,-20.5"/><polyline class="hln-ci-pipeline-check" fill="none" points="-28.4,-20.7 -26.1,-19.2 -21.4,-22.1"/></g><g class="hln-ci-pipeline-b1"><g><polygon points="-15,-0.5 -1,6.5 -1,-1.5 -15,-8.5"/><polygon points="13,-0.5 -1,6.5 -1,-1.5 13,-8.5"/><polygon points="-1,-15.5 13,-8.5 -1,-1.5 -15,-8.5"/></g><polygon class="hln-ci-pipeline-in" points="-1,-12.5 7,-8.5 -1,-4.5 -9,-8.5"/><polygon class="hln-ci-pipeline-lamp" points="-1,-12.5 7,-8.5 -1,-4.5 -9,-8.5"/><polyline class="hln-ci-pipeline-check" fill="none" points="-4.4,-8.7 -2.1,-7.2 2.6,-10.1"/></g><g class="hln-ci-pipeline-b2"><g><polygon points="9,11.5 23,18.5 23,10.5 9,3.5"/><polygon points="37,11.5 23,18.5 23,10.5 37,3.5"/><polygon points="23,-3.5 37,3.5 23,10.5 9,3.5"/></g><polygon class="hln-ci-pipeline-in" points="23,-0.5 31,3.5 23,7.5 15,3.5"/><polygon class="hln-ci-pipeline-lamp" points="23,-0.5 31,3.5 23,7.5 15,3.5"/><polyline class="hln-ci-pipeline-check" fill="none" points="19.6,3.3 21.9,4.8 26.6,1.9"/></g></g></svg>
</div>

CSS

.hln-ci-pipeline {
  --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-ci-pipeline svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-ci-pipeline svg * {
  vector-effect: non-scaling-stroke;
}
.hln-ci-pipeline .hln-ci-pipeline-in {
  stroke: #9a9ca3;
}
.hln-ci-pipeline .hln-ci-pipeline-lamp {
  fill: var(--c);
  stroke: var(--c);
  opacity: 0;
}
.hln-ci-pipeline .hln-ci-pipeline-check {
  stroke-width: 1.6;
  transform-box: fill-box;
  transform-origin: 30% 80%;
  scale: 0;
}
.hln-ci-pipeline .hln-ci-pipeline-dot {
  fill: var(--c);
  stroke: none;
  opacity: 0;
  animation: hln-ci-pipeline-dot 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-d1 {
  animation-delay: 1.5s;
}
.hln-ci-pipeline .hln-ci-pipeline-b0 {
  animation: hln-ci-pipeline-b0 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b0 .hln-ci-pipeline-lamp {
  animation: hln-ci-pipeline-l0 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b0 .hln-ci-pipeline-check {
  animation: hln-ci-pipeline-c0 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b1 {
  animation: hln-ci-pipeline-b1 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b1 .hln-ci-pipeline-lamp {
  animation: hln-ci-pipeline-l1 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b1 .hln-ci-pipeline-check {
  animation: hln-ci-pipeline-c1 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b2 {
  animation: hln-ci-pipeline-b2 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b2 .hln-ci-pipeline-lamp {
  animation: hln-ci-pipeline-l2 6s infinite;
}
.hln-ci-pipeline .hln-ci-pipeline-b2 .hln-ci-pipeline-check {
  animation: hln-ci-pipeline-c2 6s infinite;
}
@keyframes hln-ci-pipeline-b0 {
  0% { translate: 0 0; }
  5% { translate: 0 0; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  9.95% { translate: 0 calc(-4.32 * var(--u)); animation-timing-function: ease-in-out; }
  12.2% { translate: 0 calc(-3.92 * var(--u)); animation-timing-function: ease-in-out; }
  14% { translate: 0 calc(-4 * var(--u)); }
  24% { translate: 0 calc(-4 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  29% { translate: 0 0; }
  100% { translate: 0 0; }
}
@keyframes hln-ci-pipeline-l0 {
  0%, 5% { opacity: 0; }
  8%, 24% { opacity: 1; }
  28%, 100% { opacity: 0; }
}
@keyframes hln-ci-pipeline-c0 {
  0%, 26% { scale: 0; opacity: 1; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  33%, 88% { scale: 1; opacity: 1; }
  95%, 100% { scale: 1; opacity: 0; }
}
@keyframes hln-ci-pipeline-b1 {
  0% { translate: 0 0; }
  30% { translate: 0 0; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  34.95% { translate: 0 calc(-4.32 * var(--u)); animation-timing-function: ease-in-out; }
  37.2% { translate: 0 calc(-3.92 * var(--u)); animation-timing-function: ease-in-out; }
  39% { translate: 0 calc(-4 * var(--u)); }
  49% { translate: 0 calc(-4 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  54% { translate: 0 0; }
  100% { translate: 0 0; }
}
@keyframes hln-ci-pipeline-l1 {
  0%, 30% { opacity: 0; }
  33%, 49% { opacity: 1; }
  53%, 100% { opacity: 0; }
}
@keyframes hln-ci-pipeline-c1 {
  0%, 51% { scale: 0; opacity: 1; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  58%, 88% { scale: 1; opacity: 1; }
  95%, 100% { scale: 1; opacity: 0; }
}
@keyframes hln-ci-pipeline-b2 {
  0% { translate: 0 0; }
  55% { translate: 0 0; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
  59.95% { translate: 0 calc(-4.32 * var(--u)); animation-timing-function: ease-in-out; }
  62.2% { translate: 0 calc(-3.92 * var(--u)); animation-timing-function: ease-in-out; }
  64% { translate: 0 calc(-4 * var(--u)); }
  74% { translate: 0 calc(-4 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  79% { translate: 0 0; }
  100% { translate: 0 0; }
}
@keyframes hln-ci-pipeline-l2 {
  0%, 55% { opacity: 0; }
  58%, 74% { opacity: 1; }
  78%, 100% { opacity: 0; }
}
@keyframes hln-ci-pipeline-c2 {
  0%, 76% { scale: 0; opacity: 1; animation-timing-function: cubic-bezier(0.3, 1.45, 0.45, 1); }
  83%, 88% { scale: 1; opacity: 1; }
  95%, 100% { scale: 1; opacity: 0; }
}
@keyframes hln-ci-pipeline-dot {
  0%, 23% { opacity: 0; translate: 0 0; }
  24% { opacity: 1; translate: 0 0; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  30% { opacity: 1; translate: calc(10 * var(--u)) calc(5 * var(--u)); }
  31%, 100% { opacity: 0; translate: calc(10 * var(--u)) calc(5 * var(--u)); }
}
@media (prefers-reduced-motion: reduce) {
  .hln-ci-pipeline * {
    animation: none !important;
  }
  .hln-ci-pipeline .hln-ci-pipeline-check { scale: 1; }
}

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