AI CSS Animations

Push to Talk Button

A mic button that gets pressed in, fills with the accent and sends rings outward while it is held, then springs back on release. The hint below swaps between Hold to talk and Release to send.

Also known as: push to talk button css, hold to talk animation, mic button animation, voice record button css.

Hold to talk Release to send

HTML

<div class="aia-push-to-talk" role="status" aria-label="Push to talk">
  <button class="aia-push-to-talk-btn" type="button" aria-label="Hold to talk">
    <span class="aia-push-to-talk-ring"></span>
    <span class="aia-push-to-talk-ring aia-push-to-talk-ring-late"></span>
    <svg viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21"/></svg>
  </button>
  <div class="aia-push-to-talk-hint">
    <span>Hold to talk</span>
    <span class="aia-push-to-talk-live">Release to send</span>
  </div>
</div>

CSS

.aia-push-to-talk {
  --c: var(--aia-color, #7c5cff);
  font-size: var(--aia-size, 16px);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.4;
  --t: 4.4s;
  display: grid;
  justify-items: center;
  gap: 1.2em;
}
.aia-push-to-talk-btn {
  position: relative;
  display: grid;
  place-items: center;
  width: 4.6em;
  height: 4.6em;
  padding: 0;
  border: 0;
  border-radius: 50%;
  font: inherit;
  color: inherit;
  background: color-mix(in srgb, currentColor 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 14%, transparent);
  cursor: pointer;
  animation: aia-push-to-talk-press var(--t) cubic-bezier(0.3, 0.7, 0.3, 1) infinite;
}
.aia-push-to-talk-btn:focus-visible { outline: 2px solid var(--c); outline-offset: 0.25em; }
.aia-push-to-talk-btn svg {
  width: 1.7em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}
.aia-push-to-talk-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 0.12em solid var(--c);
  opacity: 0;
  animation: aia-push-to-talk-ring var(--t) cubic-bezier(0.2, 0.6, 0.35, 1) infinite;
}
.aia-push-to-talk-ring-late { animation-delay: calc(var(--t) * -0.75); }
.aia-push-to-talk-hint {
  display: grid;
  font-size: 0.9em;
  font-weight: 500;
}
.aia-push-to-talk-hint > span {
  grid-area: 1 / 1;
  text-align: center;
  color: color-mix(in srgb, currentColor 65%, transparent);
  animation: aia-push-to-talk-idle var(--t) ease infinite;
}
.aia-push-to-talk-hint > .aia-push-to-talk-live {
  color: var(--c);
  opacity: 0;
  animation-name: aia-push-to-talk-live;
}
@keyframes aia-push-to-talk-press {
  0%, 14% { scale: 1; color: inherit; background: color-mix(in srgb, currentColor 8%, transparent); }
  19% { scale: 0.88; color: #fff; background: var(--c); }
  25%, 70% { scale: 0.94; color: #fff; background: var(--c); }
  77% { scale: 1.06; color: inherit; background: color-mix(in srgb, currentColor 8%, transparent); }
  84%, 100% { scale: 1; }
}
@keyframes aia-push-to-talk-ring {
  0%, 20% { opacity: 0; scale: 1; }
  22% { opacity: 0.7; scale: 1; }
  46%, 100% { opacity: 0; scale: 1.9; }
}
@keyframes aia-push-to-talk-idle {
  0%, 15%, 76%, 100% { opacity: 1; filter: blur(0); }
  20%, 70% { opacity: 0; filter: blur(0.15em); }
}
@keyframes aia-push-to-talk-live {
  0%, 16%, 74%, 100% { opacity: 0; filter: blur(0.15em); }
  21%, 70% { opacity: 1; filter: blur(0); }
}
@media (prefers-reduced-motion: reduce) {
  .aia-push-to-talk-btn,
  .aia-push-to-talk-ring,
  .aia-push-to-talk-hint > span { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .aia-push-to-talk, .aia-push-to-talk *, .aia-push-to-talk::before, .aia-push-to-talk::after, .aia-push-to-talk *::before, .aia-push-to-talk *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --aia-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --aia-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 ai animations