AI CSS Animations

AI Command Palette Opening

A dark command palette springs open, its AI actions stagger in beneath the search row, the highlight glides down to Translate, flashes as it is chosen and the palette closes.

Also known as: ai command palette, command menu animation css, cmd k menu animation, raycast style palette.

HTML

<div class="aia-ai-command-palette" role="dialog" aria-label="AI commands">
  <div class="aia-ai-command-palette-search">
    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2C12.6 7.6 16.4 11.4 22 12C16.4 12.6 12.6 16.4 12 22C11.4 16.4 7.6 12.6 2 12C7.6 11.4 11.4 7.6 12 2Z"/></svg>
    <span class="aia-ai-command-palette-input">Ask AI or run a command<i class="aia-ai-command-palette-caret"></i></span>
    <kbd class="aia-ai-command-palette-kbd">esc</kbd>
  </div>
  <span class="aia-ai-command-palette-label">AI actions</span>
  <ul class="aia-ai-command-palette-list">
    <li class="aia-ai-command-palette-hl" aria-hidden="true"></li>
    <li style="--i: 0"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 7h14M5 12h14M5 17h9"/></svg>Summarize this page<kbd>⌘S</kbd></li>
    <li style="--i: 1"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 6h9M8.5 4v2M6 6c.8 3.5 3 6 6 7.5M11 6c-.8 3.5-3 6-6 7.5M13 20l3.5-8 3.5 8M14.2 17.5h4.6"/></svg>Translate to Spanish<kbd>⌘T</kbd></li>
    <li style="--i: 2"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 18l4-12 4 12M5.5 14h5M14 15l2.5 2.5L21 12"/></svg>Fix spelling and grammar<kbd>⌘G</kbd></li>
  </ul>
</div>

CSS

.aia-ai-command-palette {
  --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: 6.5s;
  width: 22em;
  padding: 0.4em;
  box-sizing: border-box;
  border-radius: 0.95em;
  color: #ededf0;
  background: rgba(22, 22, 27, 0.96);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.09), 0 1.4em 3em -1em rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.25);
  transform-origin: 50% 30%;
  animation: aia-ai-command-palette-open var(--t) cubic-bezier(0.3, 0.7, 0.3, 1) infinite;
}
.aia-ai-command-palette svg {
  flex: none;
  width: 1.05em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.aia-ai-command-palette-search {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.6em 0.6em 0.75em;
  margin-bottom: 0.3em;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.aia-ai-command-palette-search svg {
  fill: color-mix(in srgb, var(--c) 45%, #fff);
  stroke: none;
}
.aia-ai-command-palette-input {
  flex: 1;
  font-size: 0.95em;
  color: rgba(255, 255, 255, 0.45);
}
.aia-ai-command-palette-caret {
  display: inline-block;
  width: 0.08em;
  height: 1.1em;
  margin-left: 0.1em;
  vertical-align: -0.2em;
  background: var(--c);
  animation: aia-ai-command-palette-blink 1s steps(1) infinite;
}
.aia-ai-command-palette-kbd,
.aia-ai-command-palette-list kbd {
  padding: 0.15em 0.4em;
  border-radius: 0.35em;
  font: inherit;
  font-size: 0.72em;
  color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.07);
}
.aia-ai-command-palette-label {
  display: block;
  padding: 0.35em 0.75em 0.3em;
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
}
.aia-ai-command-palette-list {
  position: relative;
  margin: 0;
  padding: 0;
  list-style: none;
}
.aia-ai-command-palette-list li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.65em;
  height: 2.2em;
  padding: 0 0.6em;
  font-size: 0.9em;
  animation: aia-ai-command-palette-item var(--t) cubic-bezier(0.3, 0.7, 0.3, 1) infinite;
  animation-delay: calc(var(--i) * 0.07s);
}
.aia-ai-command-palette-list li kbd { margin-left: auto; }
.aia-ai-command-palette-list li svg { color: rgba(255, 255, 255, 0.6); }
.aia-ai-command-palette-list .aia-ai-command-palette-hl {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  border-radius: 0.55em;
  background: color-mix(in srgb, var(--c) 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 35%, transparent);
  animation: aia-ai-command-palette-hl var(--t) cubic-bezier(0.34, 1.3, 0.64, 1) infinite;
}
@keyframes aia-ai-command-palette-open {
  0%, 4% { opacity: 0; scale: 0.94; translate: 0 0.5em; filter: blur(0.15em); }
  12% { opacity: 1; scale: 1.01; translate: 0 0; filter: blur(0); }
  17%, 82% { opacity: 1; scale: 1; translate: 0 0; filter: blur(0); }
  90%, 100% { opacity: 0; scale: 0.97; translate: 0 0.2em; filter: blur(0.1em); }
}
@keyframes aia-ai-command-palette-item {
  0%, 8% { opacity: 0; translate: 0 0.4em; }
  16%, 100% { opacity: 1; translate: 0 0; }
}
@keyframes aia-ai-command-palette-hl {
  0%, 18% { opacity: 0; translate: 0 0; }
  22%, 38% { opacity: 1; translate: 0 0; }
  46%, 62% { opacity: 1; translate: 0 100%; background: color-mix(in srgb, var(--c) 22%, transparent); }
  66% { translate: 0 100%; background: color-mix(in srgb, var(--c) 50%, transparent); }
  72%, 100% { opacity: 1; translate: 0 100%; background: color-mix(in srgb, var(--c) 22%, transparent); }
}
@keyframes aia-ai-command-palette-blink {
  50% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .aia-ai-command-palette,
  .aia-ai-command-palette-list li,
  .aia-ai-command-palette-caret { animation: none; }
  .aia-ai-command-palette-list .aia-ai-command-palette-hl { animation: none; translate: 0 100%; }
}

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