AI CSS Animations

Router Signal Rings

A hairline isometric Wi-Fi router sends its signal out as three rings on the floor plane, each springing outward a beat after the last. The status light on the front is the single accent.

Also known as: hairline animation, isometric router animation, wifi signal animation css, router broadcast animation.

HTML

<div class="hln-router-signal" role="img" aria-label="A router sending out signal rings">
  <svg viewBox="-110 -60 220 120" aria-hidden="true">
    <g transform="translate(-9.4 -14.8) scale(.78)">
      <g transform="matrix(1 .5 -1 .5 12 19)"><g class="hln-router-signal-ring" style="--i: 0"><rect class="hln-router-signal-l hln-router-signal-o" x="-33" y="-21" width="66" height="42" rx="12"/></g><g class="hln-router-signal-ring" style="--i: 1"><rect class="hln-router-signal-l hln-router-signal-o" x="-42" y="-30" width="84" height="60" rx="21"/></g><g class="hln-router-signal-ring" style="--i: 2"><rect class="hln-router-signal-l hln-router-signal-o" x="-51" y="-39" width="102" height="78" rx="30"/></g></g>
      <g><polygon points="-23.66,6 -23.55,5.45 -23.23,4.92 -22.7,4.43 -22,4 -4,-5 -3.14,-5.35 -2.16,-5.61 -1.1,-5.77 0,-5.83 1.1,-5.77 2.16,-5.61 3.14,-5.35 4,-5 46,16 46.7,16.43 47.23,16.92 47.55,17.45 47.66,18 47.66,25 47.55,25.55 47.23,26.08 46.7,26.57 46,27 28,36 27.14,36.35 26.16,36.61 25.1,36.77 24,36.83 22.9,36.77 21.84,36.61 20.86,36.35 20,36 -22,15 -22.7,14.57 -23.23,14.08 -23.55,13.55 -23.66,13"/><polygon points="46,16 46.7,16.43 47.23,16.92 47.55,17.45 47.66,18 47.55,18.55 47.23,19.08 46.7,19.57 46,20 28,29 27.14,29.35 26.16,29.61 25.1,29.77 24,29.83 22.9,29.77 21.84,29.61 20.86,29.35 20,29 -22,8 -22.7,7.57 -23.23,7.08 -23.55,6.55 -23.66,6 -23.55,5.45 -23.23,4.92 -22.7,4.43 -22,4 -4,-5 -3.14,-5.35 -2.16,-5.61 -1.1,-5.77 0,-5.83 1.1,-5.77 2.16,-5.61 3.14,-5.35 4,-5"/></g>
      <line class="hln-router-signal-l" x1="22" y1="10" x2="38" y2="18"/>
      <line class="hln-router-signal-l" x1="18.5" y1="11.75" x2="34.5" y2="19.75"/>
      <line class="hln-router-signal-l" x1="15" y1="13.5" x2="31" y2="21.5"/>
      <line class="hln-router-signal-l" x1="11.5" y1="15.25" x2="27.5" y2="23.25"/>
      <g transform="matrix(1 .5 0 -1 -26 13)"><circle class="hln-router-signal-l" cx="8" cy="3.5" r="0.8"/><circle class="hln-router-signal-l" cx="12" cy="3.5" r="0.8"/><circle class="hln-router-signal-l" cx="16" cy="3.5" r="0.8"/><circle class="hln-router-signal-l" cx="20" cy="3.5" r="0.8"/><circle class="hln-router-signal-af" cx="26" cy="3.5" r="0.8"/><line class="hln-router-signal-l" x1="34" y1="3.5" x2="44" y2="3.5"/></g>
      <g><path d="M-1.39,-3 V-1 A3.39,1.7 0 0 0 5.39,-1 V-3 Z"/><ellipse cx="2" cy="-3" rx="3.39" ry="1.7"/></g>
      <g><path d="M0.16,-25 V-3 A1.84,0.92 0 0 0 3.84,-3 V-25 Z"/><ellipse cx="2" cy="-25" rx="1.84" ry="0.92"/></g>
      <g><path d="M34.61,15 V17 A3.39,1.7 0 0 0 41.39,17 V15 Z"/><ellipse cx="38" cy="15" rx="3.39" ry="1.7"/></g>
      <g><path d="M36.16,-7 V15 A1.84,0.92 0 0 0 39.84,15 V-7 Z"/><ellipse cx="38" cy="-7" rx="1.84" ry="0.92"/></g>
    </g>
  </svg>
</div>

CSS

.hln-router-signal {
  --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-router-signal svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-router-signal svg * {
  vector-effect: non-scaling-stroke;
}
.hln-router-signal .hln-router-signal-o {
  fill: none;
}
.hln-router-signal .hln-router-signal-l {
  stroke: #9a9ca3;
}
.hln-router-signal .hln-router-signal-af {
  fill: var(--c);
  stroke: var(--c);
}
.hln-router-signal .hln-router-signal-ring {
  animation: hln-router-signal-wave 4.5s calc(var(--i) * 0.18s) infinite both;
}
@keyframes hln-router-signal-wave {
  0% { transform: scale(.82); opacity: 0; }
  11.11% { transform: scale(.82); opacity: 0; 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); }
  28.89% { transform: scale(1); opacity: 1; }
  77.78% { transform: scale(1); opacity: 1; animation-timing-function: cubic-bezier(.65,0,.35,1); }
  87.78% { transform: scale(1.04); opacity: 0; }
  100% { transform: scale(.82); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hln-router-signal * {
    animation: none !important;
  }
}

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