AI CSS Animations

Dictation Composer Waveform

A chat composer in dictation mode: a strip of recorded waveform bars scrolls left and fades at both ends, beside a pulsing record dot, a timer, cancel and done buttons. The bars are one inline SVG.

Also known as: dictation waveform css, voice input bar animation, chatgpt dictation animation, recording waveform css.

0:14

HTML

<div class="aia-dictation-composer" role="status" aria-label="Dictating, 0:14">
  <button class="aia-dictation-composer-cancel" type="button" aria-label="Cancel dictation">
    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 7l10 10M17 7L7 17"/></svg>
  </button>
  <div class="aia-dictation-composer-wave">
    <svg class="aia-dictation-composer-bars" viewBox="0 0 240 18" preserveAspectRatio="none" aria-hidden="true"><rect x="1" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="4" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="7" y="7" width="1.6" height="4" rx="0.8"/><rect x="10" y="5" width="1.6" height="8" rx="0.8"/><rect x="13" y="3" width="1.6" height="12" rx="0.8"/><rect x="16" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="19" y="7" width="1.6" height="4" rx="0.8"/><rect x="22" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="25" y="6" width="1.6" height="6" rx="0.8"/><rect x="28" y="4" width="1.6" height="10" rx="0.8"/><rect x="31" y="1.5" width="1.6" height="15" rx="0.8"/><rect x="34" y="3.5" width="1.6" height="11" rx="0.8"/><rect x="37" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="40" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="43" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="46" y="2.5" width="1.6" height="13" rx="0.8"/><rect x="49" y="5" width="1.6" height="8" rx="0.8"/><rect x="52" y="7" width="1.6" height="4" rx="0.8"/><rect x="55" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="58" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="61" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="64" y="3" width="1.6" height="12" rx="0.8"/><rect x="67" y="1" width="1.6" height="16" rx="0.8"/><rect x="70" y="4" width="1.6" height="10" rx="0.8"/><rect x="73" y="6" width="1.6" height="6" rx="0.8"/><rect x="76" y="7" width="1.6" height="4" rx="0.8"/><rect x="79" y="5" width="1.6" height="8" rx="0.8"/><rect x="82" y="3.5" width="1.6" height="11" rx="0.8"/><rect x="85" y="6" width="1.6" height="6" rx="0.8"/><rect x="88" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="91" y="7" width="1.6" height="4" rx="0.8"/><rect x="94" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="97" y="2" width="1.6" height="14" rx="0.8"/><rect x="100" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="103" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="106" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="109" y="4" width="1.6" height="10" rx="0.8"/><rect x="112" y="6" width="1.6" height="6" rx="0.8"/><rect x="115" y="7" width="1.6" height="4" rx="0.8"/><rect x="118" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="121" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="124" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="127" y="7" width="1.6" height="4" rx="0.8"/><rect x="130" y="5" width="1.6" height="8" rx="0.8"/><rect x="133" y="3" width="1.6" height="12" rx="0.8"/><rect x="136" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="139" y="7" width="1.6" height="4" rx="0.8"/><rect x="142" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="145" y="6" width="1.6" height="6" rx="0.8"/><rect x="148" y="4" width="1.6" height="10" rx="0.8"/><rect x="151" y="1.5" width="1.6" height="15" rx="0.8"/><rect x="154" y="3.5" width="1.6" height="11" rx="0.8"/><rect x="157" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="160" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="163" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="166" y="2.5" width="1.6" height="13" rx="0.8"/><rect x="169" y="5" width="1.6" height="8" rx="0.8"/><rect x="172" y="7" width="1.6" height="4" rx="0.8"/><rect x="175" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="178" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="181" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="184" y="3" width="1.6" height="12" rx="0.8"/><rect x="187" y="1" width="1.6" height="16" rx="0.8"/><rect x="190" y="4" width="1.6" height="10" rx="0.8"/><rect x="193" y="6" width="1.6" height="6" rx="0.8"/><rect x="196" y="7" width="1.6" height="4" rx="0.8"/><rect x="199" y="5" width="1.6" height="8" rx="0.8"/><rect x="202" y="3.5" width="1.6" height="11" rx="0.8"/><rect x="205" y="6" width="1.6" height="6" rx="0.8"/><rect x="208" y="7.5" width="1.6" height="3" rx="0.8"/><rect x="211" y="7" width="1.6" height="4" rx="0.8"/><rect x="214" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="217" y="2" width="1.6" height="14" rx="0.8"/><rect x="220" y="4.5" width="1.6" height="9" rx="0.8"/><rect x="223" y="6.5" width="1.6" height="5" rx="0.8"/><rect x="226" y="5.5" width="1.6" height="7" rx="0.8"/><rect x="229" y="4" width="1.6" height="10" rx="0.8"/><rect x="232" y="6" width="1.6" height="6" rx="0.8"/><rect x="235" y="7" width="1.6" height="4" rx="0.8"/><rect x="238" y="7.5" width="1.6" height="3" rx="0.8"/></svg>
  </div>
  <span class="aia-dictation-composer-time"><i class="aia-dictation-composer-dot"></i>0:14</span>
  <button class="aia-dictation-composer-done" type="button" aria-label="Finish dictation">
    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5.5 12.5l4 4 9-9.5"/></svg>
  </button>
</div>

CSS

.aia-dictation-composer {
  --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;
  display: flex;
  align-items: center;
  gap: 0.7em;
  width: 24em;
  padding: 0.45em;
  box-sizing: border-box;
  border-radius: 99em;
  background: color-mix(in srgb, currentColor 5%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 13%, transparent);
}
.aia-dictation-composer-cancel,
.aia-dictation-composer-done {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.3em;
  height: 2.3em;
  padding: 0;
  border: 0;
  border-radius: 50%;
  font: inherit;
  color: inherit;
  background: color-mix(in srgb, currentColor 9%, transparent);
  cursor: pointer;
}
.aia-dictation-composer-done {
  color: #fff;
  background: var(--c);
  box-shadow: 0 0.3em 0.8em -0.3em color-mix(in srgb, var(--c) 80%, transparent);
}
.aia-dictation-composer-cancel svg,
.aia-dictation-composer-done svg {
  width: 1.1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.aia-dictation-composer-cancel:focus-visible,
.aia-dictation-composer-done:focus-visible { outline: 2px solid var(--c); outline-offset: 0.15em; }
.aia-dictation-composer-wave {
  flex: 1;
  height: 1.7em;
  overflow: hidden;
  color: color-mix(in srgb, currentColor 70%, transparent);
  -webkit-mask: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
  mask: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}
.aia-dictation-composer-bars {
  display: block;
  width: 200%;
  height: 100%;
  fill: currentColor;
  animation: aia-dictation-composer-scroll 5s linear infinite;
}
.aia-dictation-composer-time {
  display: flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.9em;
  font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, currentColor 75%, transparent);
}
.aia-dictation-composer-dot {
  width: 0.45em;
  height: 0.45em;
  border-radius: 50%;
  background: var(--c);
  animation: aia-dictation-composer-blink 1.2s ease-in-out infinite;
}
@keyframes aia-dictation-composer-scroll {
  to { transform: translateX(-50%); }
}
@keyframes aia-dictation-composer-blink {
  50% { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
  .aia-dictation-composer-bars,
  .aia-dictation-composer-dot { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  .aia-dictation-composer, .aia-dictation-composer *, .aia-dictation-composer::before, .aia-dictation-composer::after, .aia-dictation-composer *::before, .aia-dictation-composer *::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