AI CSS Animations

Power Bank Charging

A hairline isometric power bank: a USB-C plug slides into the port on a spring, then four charge lights fill one after another, the last in the accent. The plug tip stretches out of the port exactly.

Also known as: hairline animation, isometric battery animation, charging animation css, power bank charging.

HTML

<div class="hln-battery-charge" role="img" aria-label="A power bank charging">
  <svg viewBox="-110 -60 220 120" aria-hidden="true">
    <g transform="translate(-19 -28.8) scale(1.15)">
      <g><polygon points="-31.07,8 -30.94,7.31 -30.53,6.65 -29.88,6.04 -29,5.5 -5,-6.5 -3.93,-6.94 -2.71,-7.27 -1.38,-7.47 0,-7.54 1.38,-7.47 2.71,-7.27 3.93,-6.94 5,-6.5 57,19.5 57.88,20.04 58.53,20.65 58.94,21.31 59.07,22 59.07,31 58.94,31.69 58.53,32.35 57.88,32.96 57,33.5 33,45.5 31.93,45.94 30.71,46.27 29.38,46.47 28,46.54 26.62,46.47 25.29,46.27 24.07,45.94 23,45.5 -29,19.5 -29.88,18.96 -30.53,18.35 -30.94,17.69 -31.07,17"/><polygon points="57,19.5 57.88,20.04 58.53,20.65 58.94,21.31 59.07,22 58.94,22.69 58.53,23.35 57.88,23.96 57,24.5 33,36.5 31.93,36.94 30.71,37.27 29.38,37.47 28,37.54 26.62,37.47 25.29,37.27 24.07,36.94 23,36.5 -29,10.5 -29.88,9.96 -30.53,9.35 -30.94,8.69 -31.07,8 -30.94,7.31 -30.53,6.65 -29.88,6.04 -29,5.5 -5,-6.5 -3.93,-6.94 -2.71,-7.27 -1.38,-7.47 0,-7.54 1.38,-7.47 2.71,-7.27 3.93,-6.94 5,-6.5"/></g>
      <polygon class="hln-battery-charge-l" points="19,6.5 19.53,6.82 19.92,7.19 20.16,7.59 20.24,8 20.16,8.41 19.92,8.81 19.53,9.18 19,9.5 3,17.5 2.36,17.76 1.62,17.96 0.83,18.08 0,18.12 -0.83,18.08 -1.62,17.96 -2.36,17.76 -3,17.5 -19,9.5 -19.53,9.18 -19.92,8.81 -20.16,8.41 -20.24,8 -20.16,7.59 -19.92,7.19 -19.53,6.82 -19,6.5 -3,-1.5 -2.36,-1.76 -1.62,-1.96 -0.83,-2.08 0,-2.12 0.83,-2.08 1.62,-1.96 2.36,-1.76 3,-1.5"/>
      <ellipse class="hln-battery-charge-l" cx="12" cy="25" rx="1.56" ry="0.78"/><g class="hln-battery-charge-led" style="--i: 0"><ellipse class="hln-battery-charge-k" cx="12" cy="25" rx="1.56" ry="0.78"/></g><ellipse class="hln-battery-charge-l" cx="17" cy="27.5" rx="1.56" ry="0.78"/><g class="hln-battery-charge-led" style="--i: 1"><ellipse class="hln-battery-charge-k" cx="17" cy="27.5" rx="1.56" ry="0.78"/></g><ellipse class="hln-battery-charge-l" cx="22" cy="30" rx="1.56" ry="0.78"/><g class="hln-battery-charge-led" style="--i: 2"><ellipse class="hln-battery-charge-k" cx="22" cy="30" rx="1.56" ry="0.78"/></g><ellipse class="hln-battery-charge-l" cx="27" cy="32.5" rx="1.56" ry="0.78"/><g class="hln-battery-charge-led" style="--i: 3"><ellipse class="hln-battery-charge-af" cx="27" cy="32.5" rx="1.56" ry="0.78"/></g>
      <g transform="matrix(1 -.5 0 -1 28 48)"><rect class="hln-battery-charge-l" x="13.5" y="3.2" width="7" height="2.6" rx="1.3"/></g>
      <g transform="matrix(1 .5 -1 .5 47.4 32.5)"><rect class="hln-battery-charge-s" x="0" y="0" width="1" height="4.8"/></g>
      <g transform="matrix(1 .5 0 -1 42.6 37.5)"><rect class="hln-battery-charge-s" x="0" y="0" width="1" height="2.6"/></g>
      <g class="hln-battery-charge-plug"><g><polygon points="40.5,39.75 49.5,44.25 49.5,39.25 40.5,34.75"/><polygon points="58.5,39.75 49.5,44.25 49.5,39.25 58.5,34.75"/><polygon points="49.5,30.25 58.5,34.75 49.5,39.25 40.5,34.75"/></g><g transform="matrix(1 -.5 0 -1 49.5 44.25)"><rect class="hln-battery-charge-l" x="2.5" y="1.6" width="4" height="1.8" rx="0.9"/></g><path class="hln-battery-charge-o" d="M54,39.5 L61,43 Q67,46 61,49 L44,57.5"/></g>
    </g>
  </svg>
</div>

CSS

.hln-battery-charge {
  --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;
}
.hln-battery-charge svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-battery-charge svg * {
  vector-effect: non-scaling-stroke;
}
.hln-battery-charge .hln-battery-charge-o {
  fill: none;
}
.hln-battery-charge .hln-battery-charge-l {
  stroke: #9a9ca3;
}
.hln-battery-charge .hln-battery-charge-k {
  fill: #1c1d21;
}
.hln-battery-charge .hln-battery-charge-af {
  fill: var(--c);
  stroke: var(--c);
}
@property --hln-battery-charge-o {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
.hln-battery-charge svg {
  animation: hln-battery-charge-plug 6s infinite;
}
.hln-battery-charge .hln-battery-charge-s {
  transform: matrix(min(var(--hln-battery-charge-o), 5), 0, 0, 1, max(0, var(--hln-battery-charge-o) - 5), 0);
}
.hln-battery-charge .hln-battery-charge-plug {
  transform: matrix(1, 0, 0, 1, var(--hln-battery-charge-o), calc(var(--hln-battery-charge-o) / 2));
}
.hln-battery-charge .hln-battery-charge-led {
  animation: hln-battery-charge-led 6s calc(var(--i) * 0.45s) infinite both;
}
@keyframes hln-battery-charge-plug {
  0% { --hln-battery-charge-o: 12; }
  8.33% { --hln-battery-charge-o: 12; animation-timing-function: linear(0, 0.035, 0.125, 0.247, 0.384, 0.524, 0.655, 0.771, 0.87, 0.948, 1.008, 1.05, 1.077, 1.091, 1.095, 1.091, 1.083, 1.071, 1.058, 1.045, 1.032, 1.021, 1.012, 1.005, 0.999, 0.995, 0.993, 0.991, 0.991, 0.991, 0.992, 0.993, 1); }
  23.33% { --hln-battery-charge-o: 0; }
  81.67% { --hln-battery-charge-o: 0; animation-timing-function: cubic-bezier(.65,0,.35,1); }
  91.67% { --hln-battery-charge-o: 12; }
  100% { --hln-battery-charge-o: 12; }
}
@keyframes hln-battery-charge-led {
  0% { opacity: 0; }
  25% { opacity: 0; }
  28.33% { opacity: 1; }
  78.33% { opacity: 1; }
  81.67% { opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hln-battery-charge * {
    animation: none !important;
  }
}

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