AI CSS Animations

Search Bar Border Beam

An AI search bar that is still working: a beam with a fading tail runs around the pill at one steady speed and the status text shimmers. Three dashes on one SVG rect, offset in time, make the tail.

Also known as: border beam search bar, search bar loading animation, ai search input animation, input border beam css.

Searching 14 sources Esc

HTML

<div class="bdr-search-bar-border-beam">
  <svg class="bdr-search-bar-border-beam-svg" aria-hidden="true">
    <rect class="bdr-search-bar-border-beam-tail" width="100%" height="100%" pathLength="100"/>
    <rect class="bdr-search-bar-border-beam-body" width="100%" height="100%" pathLength="100"/>
    <rect class="bdr-search-bar-border-beam-head" width="100%" height="100%" pathLength="100"/>
  </svg>
  <svg class="bdr-search-bar-border-beam-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4 4"/></svg>
  <span class="bdr-search-bar-border-beam-text" role="status">Searching 14 sources</span>
  <kbd class="bdr-search-bar-border-beam-kbd">Esc</kbd>
</div>

CSS

.bdr-search-bar-border-beam {
  --c: var(--bdr-color, #3b82f6);
  font-size: var(--bdr-size, 16px);
  --t: 2.8s;
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6em;
  width: 18em;
  height: 2.9em;
  box-sizing: border-box;
  padding: 0 0.6em 0 1em;
  border-radius: 1.45em;
  background: #fff;
  box-shadow: 0 0 0 1px color-mix(in srgb, #0f172a 8%, transparent), 0 0.5em 1.4em -0.6em color-mix(in srgb, var(--c) 45%, transparent);
  color: #0f172a;
  font-family: system-ui, sans-serif;
}
.bdr-search-bar-border-beam-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.bdr-search-bar-border-beam-svg rect {
  rx: 1.45em;
  fill: none;
  stroke-width: 0.12em;
  stroke-linecap: round;
  animation: bdr-search-bar-border-beam-run var(--t) linear infinite;
}
/* Every dash ends at the same point: the longer ones start a little later. */
.bdr-search-bar-border-beam-svg .bdr-search-bar-border-beam-tail {
  stroke: color-mix(in srgb, var(--c) 22%, transparent);
  stroke-dasharray: 26 74;
  animation-delay: calc(var(--t) * -0.77);
}
.bdr-search-bar-border-beam-svg .bdr-search-bar-border-beam-body {
  stroke: color-mix(in srgb, var(--c) 60%, transparent);
  stroke-dasharray: 11 89;
  animation-delay: calc(var(--t) * -0.92);
}
.bdr-search-bar-border-beam-head {
  stroke: var(--c);
  stroke-width: 0.16em;
  stroke-dasharray: 3 97;
  filter: drop-shadow(0 0 0.2em var(--c));
}
.bdr-search-bar-border-beam-icon {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  fill: none;
  stroke: var(--c);
  stroke-width: 2;
  stroke-linecap: round;
}
.bdr-search-bar-border-beam-text {
  flex: 1;
  font-size: 0.85em;
  font-weight: 500;
  background: linear-gradient(90deg, #64748b 0 40%, var(--c) 50%, #64748b 60% 100%) 0 0 / 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: bdr-search-bar-border-beam-shimmer 2s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
.bdr-search-bar-border-beam-kbd {
  padding: 0.25em 0.45em;
  border-radius: 0.4em;
  background: #f1f5f9;
  box-shadow: inset 0 -1px #e2e8f0;
  color: #64748b;
  font: 600 0.65em/1 system-ui, sans-serif;
}
@keyframes bdr-search-bar-border-beam-run {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -100; }
}
@keyframes bdr-search-bar-border-beam-shimmer {
  from { background-position: 100% 0; }
  to   { background-position: 0% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bdr-search-bar-border-beam-svg rect,
  .bdr-search-bar-border-beam-text { animation-play-state: paused; }
}

@media (prefers-reduced-motion: reduce) {
  .bdr-search-bar-border-beam, .bdr-search-bar-border-beam *, .bdr-search-bar-border-beam::before, .bdr-search-bar-border-beam::after, .bdr-search-bar-border-beam *::before, .bdr-search-bar-border-beam *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

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