AI CSS Animations

Game Controller Combo

A hairline isometric game controller plays a short combo: the d-pad and face buttons press down in turn and spring back, ending on the accent button. Each button is a small cylinder.

Also known as: hairline skill, isometric controller animation, gamepad button press css.

HTML

<div class="hln-controller-press" role="img" aria-label="Buttons pressing on a game controller">
  <svg viewBox="-110 -60 220 120" aria-hidden="true">
    <g transform="translate(-18.4 -24.7) scale(1.15)">
      <g><polygon points="5.38,-1.25 5.42,-1.46 5.54,-1.66 5.74,-1.84 6,-2 7,-2.5 7.32,-2.63 7.69,-2.73 8.09,-2.79 8.5,-2.81 8.91,-2.79 9.31,-2.73 9.68,-2.63 10,-2.5 22,3.5 22.26,3.66 22.46,3.84 22.58,4.04 22.62,4.25 22.62,7.25 22.58,7.46 22.46,7.66 22.26,7.84 22,8 21,8.5 20.68,8.63 20.31,8.73 19.91,8.79 19.5,8.81 19.09,8.79 18.69,8.73 18.32,8.63 18,8.5 6,2.5 5.74,2.34 5.54,2.16 5.42,1.96 5.38,1.75"/><polygon points="22,3.5 22.26,3.66 22.46,3.84 22.58,4.04 22.62,4.25 22.58,4.46 22.46,4.66 22.26,4.84 22,5 21,5.5 20.68,5.63 20.31,5.73 19.91,5.79 19.5,5.81 19.09,5.79 18.69,5.73 18.32,5.63 18,5.5 6,-0.5 5.74,-0.66 5.54,-0.84 5.42,-1.04 5.38,-1.25 5.42,-1.46 5.54,-1.66 5.74,-1.84 6,-2 7,-2.5 7.32,-2.63 7.69,-2.73 8.09,-2.79 8.5,-2.81 8.91,-2.79 9.31,-2.73 9.68,-2.63 10,-2.5"/></g>
      <g><polygon points="42.38,17.25 42.42,17.04 42.54,16.84 42.74,16.66 43,16.5 44,16 44.32,15.87 44.69,15.77 45.09,15.71 45.5,15.69 45.91,15.71 46.31,15.77 46.68,15.87 47,16 59,22 59.26,22.16 59.46,22.34 59.58,22.54 59.62,22.75 59.62,25.75 59.58,25.96 59.46,26.16 59.26,26.34 59,26.5 58,27 57.68,27.13 57.31,27.23 56.91,27.29 56.5,27.31 56.09,27.29 55.69,27.23 55.32,27.13 55,27 43,21 42.74,20.84 42.54,20.66 42.42,20.46 42.38,20.25"/><polygon points="59,22 59.26,22.16 59.46,22.34 59.58,22.54 59.62,22.75 59.58,22.96 59.46,23.16 59.26,23.34 59,23.5 58,24 57.68,24.13 57.31,24.23 56.91,24.29 56.5,24.31 56.09,24.29 55.69,24.23 55.32,24.13 55,24 43,18 42.74,17.84 42.54,17.66 42.42,17.46 42.38,17.25 42.42,17.04 42.54,16.84 42.74,16.66 43,16.5 44,16 44.32,15.87 44.69,15.77 45.09,15.71 45.5,15.69 45.91,15.71 46.31,15.77 46.68,15.87 47,16"/></g>
      <g><polygon points="-27.56,11 -27.26,9.48 -26.37,8.02 -24.93,6.68 -23,5.5 -11,-0.5 -8.64,-1.47 -5.95,-2.19 -3.03,-2.63 0,-2.78 3.03,-2.63 5.95,-2.19 8.64,-1.47 11,-0.5 53,20.5 54.93,21.68 56.37,23.02 57.26,24.48 57.56,26 57.56,32 57.26,33.52 56.37,34.98 54.93,36.32 53,37.5 41,43.5 38.64,44.47 35.95,45.19 33.03,45.63 30,45.78 26.97,45.63 24.05,45.19 21.36,44.47 19,43.5 -23,22.5 -24.93,21.32 -26.37,19.98 -27.26,18.52 -27.56,17"/><polygon points="53,20.5 54.93,21.68 56.37,23.02 57.26,24.48 57.56,26 57.26,27.52 56.37,28.98 54.93,30.32 53,31.5 41,37.5 38.64,38.47 35.95,39.19 33.03,39.63 30,39.78 26.97,39.63 24.05,39.19 21.36,38.47 19,37.5 -23,16.5 -24.93,15.32 -26.37,13.98 -27.26,12.52 -27.56,11 -27.26,9.48 -26.37,8.02 -24.93,6.68 -23,5.5 -11,-0.5 -8.64,-1.47 -5.95,-2.19 -3.03,-2.63 0,-2.78 3.03,-2.63 5.95,-2.19 8.64,-1.47 11,-0.5"/></g>
      <g class="hln-controller-press-b" style="--i: 0"><polygon points="0.1,7.55 -2.3,8.75 -2.3,7.35 0.1,6.15"/><polygon points="-6.7,8.75 -9.1,7.55 -9.1,6.15 -6.7,7.35"/><polygon points="-4.5,9.85 -6.9,11.05 -6.9,9.65 -4.5,8.45"/><polygon points="-2.1,11.05 -4.5,9.85 -4.5,8.45 -2.1,9.65"/><polygon points="0.1,9.95 -2.1,11.05 -2.1,9.65 0.1,8.55"/><polygon points="-6.9,11.05 -9.1,9.95 -9.1,8.55 -6.9,9.65"/><polygon points="-6.9,5.05 -4.5,6.25 -2.1,5.05 0.1,6.15 -2.3,7.35 0.1,8.55 -2.1,9.65 -4.5,8.45 -6.9,9.65 -9.1,8.55 -6.7,7.35 -9.1,6.15"/></g>
      <g class="hln-controller-press-b" style="--i: 2"><g><path d="M35.89,22.7 V24.5 A3.11,1.56 0 0 0 42.11,24.5 V22.7 Z"/><ellipse cx="39" cy="22.7" rx="3.11" ry="1.56"/></g></g>
      <g class="hln-controller-press-b" style="--i: 1"><g><path d="M24.89,22.7 V24.5 A3.11,1.56 0 0 0 31.11,24.5 V22.7 Z"/><ellipse cx="28" cy="22.7" rx="3.11" ry="1.56"/></g></g>
      <g class="hln-controller-press-b" style="--i: 4"><g><path d="M35.89,28.2 V30 A3.11,1.56 0 0 0 42.11,30 V28.2 Z"/><ellipse class="hln-controller-press-af" cx="39" cy="28.2" rx="3.11" ry="1.56"/></g></g>
      <g class="hln-controller-press-b" style="--i: 3"><g><path d="M24.89,28.2 V30 A3.11,1.56 0 0 0 31.11,30 V28.2 Z"/><ellipse cx="28" cy="28.2" rx="3.11" ry="1.56"/></g></g>
      <g><path d="M-6.09,16.3 V17.5 A5.09,2.55 0 0 0 4.09,17.5 V16.3 Z"/><ellipse cx="-1" cy="16.3" rx="5.09" ry="2.55"/></g>
      <g><path d="M-4.68,14.9 V16.3 A3.68,1.84 0 0 0 2.68,16.3 V14.9 Z"/><ellipse cx="-1" cy="14.9" rx="3.68" ry="1.84"/></g>
      <ellipse class="hln-controller-press-l" cx="-1" cy="14.9" rx="2.26" ry="1.13"/>
      <g><path d="M11.91,25.3 V26.5 A5.09,2.55 0 0 0 22.09,26.5 V25.3 Z"/><ellipse cx="17" cy="25.3" rx="5.09" ry="2.55"/></g>
      <g><path d="M13.32,23.9 V25.3 A3.68,1.84 0 0 0 20.68,25.3 V23.9 Z"/><ellipse cx="17" cy="23.9" rx="3.68" ry="1.84"/></g>
      <ellipse class="hln-controller-press-l" cx="17" cy="23.9" rx="2.26" ry="1.13"/>
      <polygon class="hln-controller-press-l" points="24.5,15.25 24.76,15.41 24.96,15.59 25.08,15.79 25.12,16 25.08,16.21 24.96,16.41 24.76,16.59 24.5,16.75 24.5,16.75 24.18,16.88 23.81,16.98 23.41,17.04 23,17.06 22.59,17.04 22.19,16.98 21.82,16.88 21.5,16.75 18.5,15.25 18.24,15.09 18.04,14.91 17.92,14.71 17.88,14.5 17.92,14.29 18.04,14.09 18.24,13.91 18.5,13.75 18.5,13.75 18.82,13.62 19.19,13.52 19.59,13.46 20,13.44 20.41,13.46 20.81,13.52 21.18,13.62 21.5,13.75"/>
    </g>
  </svg>
</div>

CSS

.hln-controller-press {
  --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-controller-press svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-controller-press svg * {
  vector-effect: non-scaling-stroke;
}
.hln-controller-press .hln-controller-press-l {
  stroke: #9a9ca3;
}
.hln-controller-press .hln-controller-press-af {
  fill: var(--c);
  stroke: var(--c);
}
.hln-controller-press .hln-controller-press-b {
  animation: hln-controller-press-press 4.5s calc(var(--i) * 0.32s) infinite both;
}
@keyframes hln-controller-press-press {
  0% { transform: matrix(1, 0, 0, 1, 0, 0); }
  11.11% { transform: matrix(1, 0, 0, 1, 0, 0); animation-timing-function: cubic-bezier(.55,0,.85,.3); }
  12.89% { transform: matrix(1, 0, 0, 1, 0, 1.2); }
  13.78% { transform: matrix(1, 0, 0, 1, 0, 1.2); 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); }
  26.67% { transform: matrix(1, 0, 0, 1, 0, 0); }
  100% { transform: matrix(1, 0, 0, 1, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hln-controller-press * {
    animation: none !important;
  }
}

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