36 CSS Search Bars
05 / 36

All 36 in 36 CSS Search Bars

  1. 01Command Palette Cmd+K Search Bar
  2. 02Algolia-Style Instant Search with Highlighted Results Dropdown
  3. 03E-Commerce Product Search Bar with Category Scope Dropdown
  4. 04Header Navbar Integrated Sticky Search Bar
  5. 05SaaS Dashboard Command Search with Recent and Suggested
  6. 06Minimal CSS Search Bar with Animated Underline
  7. 07CSS Rounded Pill Search Bar with Submit Button
  8. 08Glassmorphism CSS Search Bar (Backdrop Blur)
  9. 09Neon Glow CSS Search Bar (Cyberpunk)
  10. 10CSS Search Bar with Animated Caret Highlight
  11. 11CSS Search Bar with Voice Input Microphone Button
  12. 12CSS Search Bar with Loading Spinner Indicator
  13. 13CSS Search Bar with Clear Button (X on Type)
  14. 14Animated Expanding CSS Search Bar on Focus
  15. 15CSS Search Bar with Autocomplete Suggestions Dropdown
  16. 16CSS Search Bar with Keyboard Shortcut Hint (Cmd K / Ctrl K)
  17. 17CSS Search Bar with Filter Chip Tags
  18. 18CSS Search Bar with Recent Searches Dropdown
  19. 19CSS Search Bar with Rotating Placeholder Text
  20. 20CSS People Search Bar with Avatar Chips
  21. 21Neo-Brutalist CSS Search Bar with Offset Stamp
  22. 22Compact Toolbar CSS Search Bar (Docs / Wiki)
  23. 23Hero Section CSS Search Bar with CTA
  24. 24CSS Search Bar with Side Category Indicator
  25. 25Floating CSS Search Bar with Drop Shadow (Elevated)
  26. 26CSS Search + Filter Sidebar Combo Bar
  27. 27CSS Search Bar with Inline Loading Progress Bar
  28. 28CSS Search Bar with Dual-Tone Border Outline
  29. 29CSS Glitch Search Bar with RGB Split Effect
  30. 30Mobile-First Compact CSS Search Bar
  31. 31CSS Search Bar with Focus Ring Bloom Animation
  32. 32CSS Search Bar Combo with Scope Selector
  33. 33CSS Search Bar with Inset Pressed 3D Effect
  34. 34CSS Search Bar with Animated Border Trace
  35. 35Floating Card CSS Search Bar (Modal Style)
  36. 36Aurora Gradient CSS Search Bar
Light JSMIT licensed

SaaS Dashboard Command Search with Recent and Suggested

The persistent dashboard topbar search: focus it and a rich panel opens with Recent (clock icons), Suggested (sparkle icons) and Quick actions with real ⌘ shortcuts. Dark-first, arrow-key navigable, and mounted in a mock admin shell so you can see it in context.

Live Demo
Try it

Nucleo: 44,000+ SVG icons in five families · All Icons Bundle $149

Nucleo · Affiliate link

Get the Nucleo bundle

The code

<div class="sb-05">
  <button class="sb-05__theme" type="button" aria-pressed="false" aria-label="Switch to dark theme">
    <svg class="sb-05__moon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M20 14.2A8.2 8.2 0 0 1 9.8 4 8.4 8.4 0 1 0 20 14.2"/></svg>
    <svg class="sb-05__sun" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 3.4v2M12 18.6v2M3.4 12h2M18.6 12h2M6 6l1.4 1.4M16.6 16.6 18 18M18 6l-1.4 1.4M7.4 16.6 6 18"/></svg>
  </button>
  <div class="sb-05__stage">
    <div class="sb-05__shell">
      <aside class="sb-05__rail" aria-hidden="true">
        <span class="sb-05__mark"></span>
        <span class="sb-05__railitem sb-05__railitem--on"></span>
        <span class="sb-05__railitem"></span>
        <span class="sb-05__railitem"></span>
        <span class="sb-05__railitem"></span>
      </aside>

      <div class="sb-05__main">
        <header class="sb-05__topbar">
          <div class="sb-05__combo" role="search">
            <div class="sb-05__field">
              <svg class="sb-05__ico" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="6.4" stroke="currentColor" stroke-width="1.7"/><path d="m16 16 4.2 4.2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
              <label class="sb-05__vh" for="sb-05-input">Search customers, invoices and actions</label>
              <input class="sb-05__input" id="sb-05-input" type="search" role="combobox" placeholder="Search or run a command&hellip;" autocomplete="off" spellcheck="false" aria-controls="sb-05-list" aria-expanded="false" aria-activedescendant="sb-05-r1">
              <kbd class="sb-05__kbd">&#8984;K</kbd>
            </div>

            <div class="sb-05__panel">
              <ul class="sb-05__list" id="sb-05-list" role="listbox" aria-label="Search results and actions">
                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h1">Recent</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h1">
                    <li class="sb-05__row" role="option" id="sb-05-r1" aria-selected="true">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Q3 revenue<small>Reports</small></span>
                      <time class="sb-05__meta" datetime="2027-02-11T09:20">9:20 AM</time>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r2" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">invoice template<small>Documents</small></span>
                      <time class="sb-05__meta" datetime="2027-02-10T16:04">Yesterday</time>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r3" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Sam Rivera<small>Customer &middot; #40219</small></span>
                      <time class="sb-05__meta" datetime="2027-02-09T11:12">Mon</time>
                    </li>
                  </ul>
                </li>

                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h2">Suggested</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h2">
                    <li class="sb-05__row" role="option" id="sb-05-r4" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M18 16.5l.8 2.1 2.1.8-2.1.8-.8 2.1-.8-2.1-2.1-.8 2.1-.8z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Churn risk accounts this week<small>Generated view</small></span>
                      <span class="sb-05__pill">New</span>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r5" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Failed payments &gt; $500<small>Saved filter</small></span>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r6" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Compare MRR to last quarter<small>Insight</small></span>
                    </li>
                  </ul>
                </li>

                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h3">Quick actions</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h3">
                    <li class="sb-05__row" role="option" id="sb-05-r7" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">New invoice</span>
                      <kbd class="sb-05__kbd">&#8984;&#8679;N</kbd>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r8" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="2.7" stroke="currentColor" stroke-width="1.6"/><path d="M12 4.2v2.4m0 10.8v2.4M4.2 12h2.4m10.8 0h2.4M6.7 6.7l1.7 1.7m7.2 7.2 1.7 1.7m0-10.6-1.7 1.7M8.4 15.6l-1.7 1.7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Settings</span>
                      <kbd class="sb-05__kbd">&#8984;,</kbd>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r9" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.8" stroke="currentColor" stroke-width="1.6"/><path d="M9.9 9.6a2.2 2.2 0 1 1 3.2 2c-.7.4-1.1.9-1.1 1.7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="16.4" r=".9" fill="currentColor"/></svg></span>
                      <span class="sb-05__txt">Help &amp; docs</span>
                      <kbd class="sb-05__kbd">&#8984;/</kbd>
                    </li>
                  </ul>
                </li>
              </ul>
            </div>
          </div>

          <div class="sb-05__topright" aria-hidden="true">
            <span class="sb-05__chip"></span>
            <span class="sb-05__avatar">AC</span>
          </div>
        </header>

        <div class="sb-05__body" aria-hidden="true">
          <div class="sb-05__cards">
            <span class="sb-05__card"></span>
            <span class="sb-05__card"></span>
            <span class="sb-05__card"></span>
          </div>
          <span class="sb-05__chart"></span>
        </div>
      </div>
    </div>
  </div>
</div>
.sb-05 {
  --bg: #07080d;
  --shell: #0d0f16;
  --panel: #12141d;
  --panel-2: #181b26;
  --ink: #f2f3f8;
  --muted: #8b90a4;
  --line: #222634;
  --acc: #7c6cff;
  --acc-2: #2dd4bf;
  --wash: rgba(124,108,255,.14);
  --ring: #9c90ff;
  --shadow: rgba(0,0,0,.72);
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  box-sizing: border-box;
  font-family: system-ui,-apple-system,"Segoe UI",sans-serif;
  color: var(--ink);
  background: radial-gradient(52rem 32rem at 88% -10%, rgba(124,108,255,.18), transparent 68%), radial-gradient(40rem 26rem at -6% 104%, rgba(45,212,191,.12), transparent 68%), var(--bg);
  -webkit-font-smoothing: antialiased;
}

.sb-05 *,
.sb-05 *::before,
.sb-05 *::after {
  box-sizing: border-box;
}

@supports (color: oklch(50% .1 280)) {
  .sb-05 {
    --shell: oklch(16% .015 280);
    --panel: oklch(19% .018 280);
    --panel-2: oklch(24% .02 280);
    --ink: oklch(97% .005 280);
    --muted: oklch(68% .02 280);
    --line: oklch(28% .018 280);
    --acc: oklch(68% .18 292);
    --acc-2: oklch(78% .13 180);
    --wash: color-mix(in oklab, oklch(68% .18 292) 16%, transparent);
  }
}

.sb-05__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(1rem,4vw,3rem);
}

.sb-05__vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sb-05__shell {
  display: flex;
  inline-size: min(62rem,100%);
  block-size: min(32rem,82svh);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--shell);
  box-shadow: 0 40px 80px -34px var(--shadow), 0 0 0 1px rgba(255,255,255,.03) inset;
}

.sb-05__rail {
  flex: none;
  inline-size: 60px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  padding: 1rem .5rem;
  border-inline-end: 1px solid var(--line);
  background: rgba(255,255,255,.015);
}

.sb-05__mark {
  inline-size: 26px;
  block-size: 26px;
  border-radius: 8px;
  background: conic-gradient(from 210deg,#7c6cff,#c084fc 45%,#2dd4bf 80%,#7c6cff);
  margin-block-end: .6rem;
}

.sb-05__railitem {
  inline-size: 24px;
  block-size: 24px;
  border-radius: 7px;
  background: var(--panel-2);
}

.sb-05__railitem--on {
  background: var(--wash);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--acc) 40%, transparent);
}

.sb-05__main {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
}

.sb-05__topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .85rem 1rem;
  border-block-end: 1px solid var(--line);
  background: rgba(255,255,255,.012);
}

.sb-05__combo {
  position: relative;
  flex: 1;
  min-inline-size: 0;
  max-inline-size: 34rem;
}

.sb-05__field {
  display: flex;
  align-items: center;
  gap: .65rem;
  min-block-size: 44px;
  padding-inline: .85rem .5rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  transition: border-color .2s, box-shadow .2s, background .2s;
}

.sb-05__combo:focus-within .sb-05__field {
  border-color: color-mix(in oklab, var(--acc) 55%, var(--line));
  box-shadow: 0 0 0 4px var(--wash);
  background: var(--panel-2);
}

.sb-05__ico {
  inline-size: 18px;
  block-size: 18px;
  flex: none;
  color: var(--muted);
  transition: color .2s;
}

.sb-05__combo:focus-within .sb-05__ico {
  color: var(--acc);
}

.sb-05__input {
  flex: 1;
  min-inline-size: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: 400 .93rem/1 inherit;
}

.sb-05__input::placeholder {
  color: var(--muted);
}

.sb-05__input:focus {
  outline: none;
}

.sb-05__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.sb-05__kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 1.7rem;
  block-size: 1.5rem;
  padding-inline: .38rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--muted);
  font: 500 .7rem/1 ui-monospace,"SF Mono",Menlo,monospace;
  font-variant-numeric: tabular-nums;
}
/* panel */

.sb-05__panel {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% + .45rem);
  z-index: 8;
  max-block-size: min(24rem,60svh);
  overflow: auto;
  overscroll-behavior: contain;
  padding: .4rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 30px 60px -22px var(--shadow), 0 0 0 1px rgba(255,255,255,.04) inset;
  opacity: 0;
  translate: 0 -8px;
  scale: .99;
  visibility: hidden;
  transform-origin: top center;
  transition: opacity .2s cubic-bezier(.2,.9,.25,1), translate .2s cubic-bezier(.2,.9,.25,1), scale .2s, visibility .2s;
}

.sb-05__combo:focus-within .sb-05__panel {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  visibility: visible;
}

.sb-05__list,
.sb-05__sub {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sb-05__sect-h {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  margin: 0;
  padding: .55rem .65rem .3rem;
  background: var(--panel);
  color: var(--muted);
  font: 600 .67rem/1 inherit;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.sb-05__sect:not(:has(.sb-05__row:not([hidden]))) {
  display: none;
}

.sb-05__row {
  display: flex;
  align-items: center;
  gap: .7rem;
  min-block-size: 44px;
  padding: .4rem .65rem;
  border-radius: 10px;
  cursor: pointer;
  scroll-margin: 2rem;
  transition: background .14s;
}

.sb-05__row:hover {
  background: rgba(255,255,255,.04);
}

.sb-05__row[aria-selected="true"] {
  background: var(--wash);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--acc) 32%, transparent);
}

.sb-05__glyph {
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  flex: none;
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--muted);
}

.sb-05__glyph svg {
  inline-size: 16px;
  block-size: 16px;
}

.sb-05__glyph--ai {
  color: var(--acc-2);
  background: color-mix(in oklab, var(--acc-2) 14%, var(--panel-2));
}

.sb-05__txt {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  flex: 1;
  min-inline-size: 0;
  font: 500 .89rem/1.25 inherit;
}

.sb-05__txt small {
  color: var(--muted);
  font: 400 .74rem/1.3 inherit;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sb-05__meta {
  color: var(--muted);
  font: 400 .74rem/1 inherit;
  font-variant-numeric: tabular-nums;
  flex: none;
}

.sb-05__pill {
  flex: none;
  padding: .2rem .45rem;
  border-radius: 999px;
  background: color-mix(in oklab, var(--acc-2) 20%, transparent);
  color: var(--acc-2);
  font: 600 .66rem/1 inherit;
  letter-spacing: .04em;
  text-transform: uppercase;
}
/* shell chrome */

.sb-05__topright {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex: none;
}

.sb-05__chip {
  inline-size: 64px;
  block-size: 26px;
  border-radius: 8px;
  background: var(--panel-2);
}

.sb-05__avatar {
  display: grid;
  place-items: center;
  inline-size: 32px;
  block-size: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg,#7c6cff,#4f46e5);
  color: #fff;
  font: 600 .72rem/1 inherit;
}

.sb-05__body {
  flex: 1;
  display: grid;
  gap: 1rem;
  grid-template-rows: auto 1fr;
  padding: 1rem;
  opacity: .55;
}

.sb-05__cards {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: 1rem;
}

.sb-05__card {
  block-size: 5.5rem;
  border-radius: 12px;
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--line);
}

.sb-05__chart {
  border-radius: 12px;
  background: linear-gradient(180deg, var(--wash), transparent 70%), var(--panel);
  box-shadow: inset 0 0 0 1px var(--line);
}

.sb-05 :focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}
/* light fallback (this demo is dark-first) */

.sb-05[data-theme="light"] {
  --bg: #f5f6fa;
  --shell: #fff;
  --panel: #fff;
  --panel-2: #f3f4f9;
  --ink: #12141c;
  --muted: #6b7080;
  --line: #e5e7f0;
  --acc: #6455f0;
  --acc-2: #0d9488;
  --wash: rgba(100,85,240,.10);
  --ring: #6455f0;
  --shadow: rgba(20,22,40,.2);
  background: radial-gradient(52rem 32rem at 88% -10%, rgba(100,85,240,.10), transparent 68%), var(--bg);
}

.sb-05[data-theme="light"] .sb-05__row:hover {
  background: #f5f6fa;
}

@media (prefers-color-scheme: light) {
  .sb-05:not([data-theme="dark"]) {
    --bg: #f5f6fa;
    --shell: #fff;
    --panel: #fff;
    --panel-2: #f3f4f9;
    --ink: #12141c;
    --muted: #6b7080;
    --line: #e5e7f0;
    --acc: #6455f0;
    --acc-2: #0d9488;
    --wash: rgba(100,85,240,.10);
    --ring: #6455f0;
    --shadow: rgba(20,22,40,.2);
    background: radial-gradient(52rem 32rem at 88% -10%, rgba(100,85,240,.10), transparent 68%), var(--bg);
  }

  .sb-05:not([data-theme="dark"]) .sb-05__row:hover {
    background: #f5f6fa;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sb-05 *,
    .sb-05 *::before,
    .sb-05 *::after {
    animation: none !important;
    transition: none !important;
  }
}

@media (forced-colors: active) {
  .sb-05__field,
    .sb-05__panel,
    .sb-05__shell {
    border: 1px solid CanvasText;
  }

  .sb-05__row[aria-selected="true"] {
    outline: 2px solid Highlight;
  }
}

.sb-05__theme {
  position: absolute;
  inset-block-start: clamp(.75rem,2vw,1.25rem);
  inset-inline-end: clamp(.75rem,2vw,1.25rem);
  z-index: 50;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(0,0,0,.12);
  color: currentColor;
  background: rgba(255,255,255,.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: background .25s ease, transform .25s cubic-bezier(.16,1,.3,1), border-color .25s ease;
}

.sb-05[data-theme="dark"] .sb-05__theme {
  background: rgba(20,20,28,.72);
  border-color: rgba(255,255,255,.15);
  color: #fff;
}

@media (prefers-color-scheme: dark) {
  .sb-05:not([data-theme="light"]) .sb-05__theme {
    background: rgba(20,20,28,.72);
    border-color: rgba(255,255,255,.15);
    color: #fff;
  }
}

.sb-05__theme:hover {
  transform: translateY(-1px);
  border-color: rgba(0,0,0,.24);
}

.sb-05[data-theme="dark"] .sb-05__theme:hover,
.sb-05:not([data-theme="light"]) .sb-05__theme:hover {
  border-color: rgba(255,255,255,.3);
}

.sb-05__theme:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

.sb-05__theme svg {
  grid-area: 1/1;
  inline-size: 1.1rem;
  block-size: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sb-05__sun {
  display: none;
}

.sb-05__theme[aria-pressed="true"] .sb-05__sun {
  display: block;
}

.sb-05__theme[aria-pressed="true"] .sb-05__moon {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .sb-05__theme {
    transition: none;
  }

  .sb-05__theme:hover {
    transform: none;
  }
}
(() => {
  const root = document.querySelector('.sb-05');
  if (!root) return;
  const combo = root.querySelector('.sb-05__combo');
  const input = root.querySelector('#sb-05-input');
  const rows = [...root.querySelectorAll('.sb-05__row')];

  const select = (el) => {
    if (!el) return;
    rows.forEach((r) => r.setAttribute('aria-selected', String(r === el)));
    input.setAttribute('aria-activedescendant', el.id);
    el.scrollIntoView({ block: 'nearest' });
  };
  const index = () => rows.findIndex((r) => r.getAttribute('aria-selected') === 'true');

  input.addEventListener('focus', () => input.setAttribute('aria-expanded', 'true'));
  input.addEventListener('blur', () => input.setAttribute('aria-expanded', 'false'));
  input.addEventListener('keydown', (e) => {
    const i = index();
    if (e.key === 'ArrowDown') { e.preventDefault(); select(rows[(i + 1) % rows.length]); }
    if (e.key === 'ArrowUp') { e.preventDefault(); select(rows[(i - 1 + rows.length) % rows.length]); }
    if (e.key === 'Enter') { e.preventDefault(); rows[i] && rows[i].animate([{ scale: '.985' }, { scale: '1' }], 150); }
    if (e.key === 'Escape') { input.blur(); }
  });
  rows.forEach((r) => {
    r.addEventListener('mousemove', () => select(r));
    r.addEventListener('mousedown', (e) => e.preventDefault());   /* keep focus in the field */
  });
  document.addEventListener('keydown', (e) => {
    if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); input.focus(); input.select(); }
  });
})();
(()=>{const r=document.querySelector('.sb-05');if(!r)return;const t=r.querySelector('.sb-05__theme');if(!t)return;const dark=()=>(r.dataset.theme||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'))==='dark';const sync=()=>{t.setAttribute('aria-pressed',String(dark()));t.setAttribute('aria-label',dark()?'Switch to light theme':'Switch to dark theme');};t.addEventListener('click',()=>{r.dataset.theme=dark()?'light':'dark';sync();});matchMedia('(prefers-color-scheme: dark)').addEventListener('change',()=>{if(!r.dataset.theme)sync();});sync();})();
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Search Bar from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: SaaS Dashboard Command Search with Recent and Suggested
Source: https://codefronts.com/components/css-search-boxes/saas-dashboard-command-search-with-recent-and-suggested/

The persistent dashboard topbar search: focus it and a rich panel opens with Recent (clock icons), Suggested (sparkle icons) and Quick actions with real ⌘ shortcuts. Dark-first, arrow-key navigable, and mounted in a mock admin shell so you can see it in context.
## HTML
```html
<div class="sb-05">
  <button class="sb-05__theme" type="button" aria-pressed="false" aria-label="Switch to dark theme">
    <svg class="sb-05__moon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M20 14.2A8.2 8.2 0 0 1 9.8 4 8.4 8.4 0 1 0 20 14.2"/></svg>
    <svg class="sb-05__sun" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 3.4v2M12 18.6v2M3.4 12h2M18.6 12h2M6 6l1.4 1.4M16.6 16.6 18 18M18 6l-1.4 1.4M7.4 16.6 6 18"/></svg>
  </button>
  <div class="sb-05__stage">
    <div class="sb-05__shell">
      <aside class="sb-05__rail" aria-hidden="true">
        <span class="sb-05__mark"></span>
        <span class="sb-05__railitem sb-05__railitem--on"></span>
        <span class="sb-05__railitem"></span>
        <span class="sb-05__railitem"></span>
        <span class="sb-05__railitem"></span>
      </aside>

      <div class="sb-05__main">
        <header class="sb-05__topbar">
          <div class="sb-05__combo" role="search">
            <div class="sb-05__field">
              <svg class="sb-05__ico" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false"><circle cx="11" cy="11" r="6.4" stroke="currentColor" stroke-width="1.7"/><path d="m16 16 4.2 4.2" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
              <label class="sb-05__vh" for="sb-05-input">Search customers, invoices and actions</label>
              <input class="sb-05__input" id="sb-05-input" type="search" role="combobox" placeholder="Search or run a command&hellip;" autocomplete="off" spellcheck="false" aria-controls="sb-05-list" aria-expanded="false" aria-activedescendant="sb-05-r1">
              <kbd class="sb-05__kbd">&#8984;K</kbd>
            </div>

            <div class="sb-05__panel">
              <ul class="sb-05__list" id="sb-05-list" role="listbox" aria-label="Search results and actions">
                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h1">Recent</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h1">
                    <li class="sb-05__row" role="option" id="sb-05-r1" aria-selected="true">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Q3 revenue<small>Reports</small></span>
                      <time class="sb-05__meta" datetime="2027-02-11T09:20">9:20 AM</time>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r2" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">invoice template<small>Documents</small></span>
                      <time class="sb-05__meta" datetime="2027-02-10T16:04">Yesterday</time>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r3" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.6" stroke="currentColor" stroke-width="1.6"/><path d="M12 8.4V12l2.6 1.6" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Sam Rivera<small>Customer &middot; #40219</small></span>
                      <time class="sb-05__meta" datetime="2027-02-09T11:12">Mon</time>
                    </li>
                  </ul>
                </li>

                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h2">Suggested</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h2">
                    <li class="sb-05__row" role="option" id="sb-05-r4" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M18 16.5l.8 2.1 2.1.8-2.1.8-.8 2.1-.8-2.1-2.1-.8 2.1-.8z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Churn risk accounts this week<small>Generated view</small></span>
                      <span class="sb-05__pill">New</span>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r5" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Failed payments &gt; $500<small>Saved filter</small></span>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r6" aria-selected="false">
                      <span class="sb-05__glyph sb-05__glyph--ai" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 3.5l1.7 4.6 4.6 1.7-4.6 1.7L12 16.1l-1.7-4.6L5.7 9.8l4.6-1.7z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/></svg></span>
                      <span class="sb-05__txt">Compare MRR to last quarter<small>Insight</small></span>
                    </li>
                  </ul>
                </li>

                <li class="sb-05__sect" role="presentation">
                  <p class="sb-05__sect-h" id="sb-05-h3">Quick actions</p>
                  <ul class="sb-05__sub" role="group" aria-labelledby="sb-05-h3">
                    <li class="sb-05__row" role="option" id="sb-05-r7" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">New invoice</span>
                      <kbd class="sb-05__kbd">&#8984;&#8679;N</kbd>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r8" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="2.7" stroke="currentColor" stroke-width="1.6"/><path d="M12 4.2v2.4m0 10.8v2.4M4.2 12h2.4m10.8 0h2.4M6.7 6.7l1.7 1.7m7.2 7.2 1.7 1.7m0-10.6-1.7 1.7M8.4 15.6l-1.7 1.7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
                      <span class="sb-05__txt">Settings</span>
                      <kbd class="sb-05__kbd">&#8984;,</kbd>
                    </li>
                    <li class="sb-05__row" role="option" id="sb-05-r9" aria-selected="false">
                      <span class="sb-05__glyph" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="7.8" stroke="currentColor" stroke-width="1.6"/><path d="M9.9 9.6a2.2 2.2 0 1 1 3.2 2c-.7.4-1.1.9-1.1 1.7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><circle cx="12" cy="16.4" r=".9" fill="currentColor"/></svg></span>
                      <span class="sb-05__txt">Help &amp; docs</span>
                      <kbd class="sb-05__kbd">&#8984;/</kbd>
                    </li>
                  </ul>
                </li>
              </ul>
            </div>
          </div>

          <div class="sb-05__topright" aria-hidden="true">
            <span class="sb-05__chip"></span>
            <span class="sb-05__avatar">AC</span>
          </div>
        </header>

        <div class="sb-05__body" aria-hidden="true">
          <div class="sb-05__cards">
            <span class="sb-05__card"></span>
            <span class="sb-05__card"></span>
            <span class="sb-05__card"></span>
          </div>
          <span class="sb-05__chart"></span>
        </div>
      </div>
    </div>
  </div>
</div>
```
## CSS
```css
.sb-05 {
  --bg: #07080d;
  --shell: #0d0f16;
  --panel: #12141d;
  --panel-2: #181b26;
  --ink: #f2f3f8;
  --muted: #8b90a4;
  --line: #222634;
  --acc: #7c6cff;
  --acc-2: #2dd4bf;
  --wash: rgba(124,108,255,.14);
  --ring: #9c90ff;
  --shadow: rgba(0,0,0,.72);
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: block;
  box-sizing: border-box;
  font-family: system-ui,-apple-system,"Segoe UI",sans-serif;
  color: var(--ink);
  background: radial-gradient(52rem 32rem at 88% -10%, rgba(124,108,255,.18), transparent 68%), radial-gradient(40rem 26rem at -6% 104%, rgba(45,212,191,.12), transparent 68%), var(--bg);
  -webkit-font-smoothing: antialiased;
}

.sb-05 *,
.sb-05 *::before,
.sb-05 *::after {
  box-sizing: border-box;
}

@supports (color: oklch(50% .1 280)) {
  .sb-05 {
    --shell: oklch(16% .015 280);
    --panel: oklch(19% .018 280);
    --panel-2: oklch(24% .02 280);
    --ink: oklch(97% .005 280);
    --muted: oklch(68% .02 280);
    --line: oklch(28% .018 280);
    --acc: oklch(68% .18 292);
    --acc-2: oklch(78% .13 180);
    --wash: color-mix(in oklab, oklch(68% .18 292) 16%, transparent);
  }
}

.sb-05__stage {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: clamp(1rem,4vw,3rem);
}

.sb-05__vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.sb-05__shell {
  display: flex;
  inline-size: min(62rem,100%);
  block-size: min(32rem,82svh);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--shell);
  box-shadow: 0 40px 80px -34px var(--shadow), 0 0 0 1px rgba(255,255,255,.03) inset;
}

.sb-05__rail {
  flex: none;
  inline-size: 60px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  padding: 1rem .5rem;
  border-inline-end: 1px solid var(--line);
  background: rgba(255,255,255,.015);
}

.sb-05__mark {
  inline-size: 26px;
  block-size: 26px;
  border-radius: 8px;
  background: conic-gradient(from 210deg,#7c6cff,#c084fc 45%,#2dd4bf 80%,#7c6cff);
  margin-block-end: .6rem;
}

.sb-05__railitem {
  inline-size: 24px;
  block-size: 24px;
  border-radius: 7px;
  background: var(--panel-2);
}

.sb-05__railitem--on {
  background: var(--wash);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--acc) 40%, transparent);
}

.sb-05__main {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
}

.sb-05__topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: .85rem 1rem;
  border-block-end: 1px solid var(--line);
  background: rgba(255,255,255,.012);
}

.sb-05__combo {
  position: relative;
  flex: 1;
  min-inline-size: 0;
  max-inline-size: 34rem;
}

.sb-05__field {
  display: flex;
  align-items: center;
  gap: .65rem;
  min-block-size: 44px;
  padding-inline: .85rem .5rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  transition: border-color .2s, box-shadow .2s, background .2s;
}

.sb-05__combo:focus-within .sb-05__field {
  border-color: color-mix(in oklab, var(--acc) 55%, var(--line));
  box-shadow: 0 0 0 4px var(--wash);
  background: var(--panel-2);
}

.sb-05__ico {
  inline-size: 18px;
  block-size: 18px;
  flex: none;
  color: var(--muted);
  transition: color .2s;
}

.sb-05__combo:focus-within .sb-05__ico {
  color: var(--acc);
}

.sb-05__input {
  flex: 1;
  min-inline-size: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: 400 .93rem/1 inherit;
}

.sb-05__input::placeholder {
  color: var(--muted);
}

.sb-05__input:focus {
  outline: none;
}

.sb-05__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.sb-05__kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 1.7rem;
  block-size: 1.5rem;
  padding-inline: .38rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--muted);
  font: 500 .7rem/1 ui-monospace,"SF Mono",Menlo,monospace;
  font-variant-numeric: tabular-nums;
}
/* panel */

.sb-05__panel {
  position: absolute;
  inset-inline: 0;
  inset-block-start: calc(100% + .45rem);
  z-index: 8;
  max-block-size: min(24rem,60svh);
  overflow: auto;
  overscroll-behavior: contain;
  padding: .4rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: 0 30px 60px -22px var(--shadow), 0 0 0 1px rgba(255,255,255,.04) inset;
  opacity: 0;
  translate: 0 -8px;
  scale: .99;
  visibility: hidden;
  transform-origin: top center;
  transition: opacity .2s cubic-bezier(.2,.9,.25,1), translate .2s cubic-bezier(.2,.9,.25,1), scale .2s, visibility .2s;
}

.sb-05__combo:focus-within .sb-05__panel {
  opacity: 1;
  translate: 0 0;
  scale: 1;
  visibility: visible;
}

.sb-05__list,
.sb-05__sub {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sb-05__sect-h {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  margin: 0;
  padding: .55rem .65rem .3rem;
  background: var(--panel);
  color: var(--muted);
  font: 600 .67rem/1 inherit;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.sb-05__sect:not(:has(.sb-05__row:not([hidden]))) {
  display: none;
}

.sb-05__row {
  display: flex;
  align-items: center;
  gap: .7rem;
  min-block-size: 44px;
  padding: .4rem .65rem;
  border-radius: 10px;
  cursor: pointer;
  scroll-margin: 2rem;
  transition: background .14s;
}

.sb-05__row:hover {
  background: rgba(255,255,255,.04);
}

.sb-05__row[aria-selected="true"] {
  background: var(--wash);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--acc) 32%, transparent);
}

.sb-05__glyph {
  display: grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  flex: none;
  border-radius: 8px;
  background: var(--panel-2);
  color: var(--muted);
}

.sb-05__glyph svg {
  inline-size: 16px;
  block-size: 16px;
}

.sb-05__glyph--ai {
  color: var(--acc-2);
  background: color-mix(in oklab, var(--acc-2) 14%, var(--panel-2));
}

.sb-05__txt {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  flex: 1;
  min-inline-size: 0;
  font: 500 .89rem/1.25 inherit;
}

.sb-05__txt small {
  color: var(--muted);
  font: 400 .74rem/1.3 inherit;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sb-05__meta {
  color: var(--muted);
  font: 400 .74rem/1 inherit;
  font-variant-numeric: tabular-nums;
  flex: none;
}

.sb-05__pill {
  flex: none;
  padding: .2rem .45rem;
  border-radius: 999px;
  background: color-mix(in oklab, var(--acc-2) 20%, transparent);
  color: var(--acc-2);
  font: 600 .66rem/1 inherit;
  letter-spacing: .04em;
  text-transform: uppercase;
}
/* shell chrome */

.sb-05__topright {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex: none;
}

.sb-05__chip {
  inline-size: 64px;
  block-size: 26px;
  border-radius: 8px;
  background: var(--panel-2);
}

.sb-05__avatar {
  display: grid;
  place-items: center;
  inline-size: 32px;
  block-size: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg,#7c6cff,#4f46e5);
  color: #fff;
  font: 600 .72rem/1 inherit;
}

.sb-05__body {
  flex: 1;
  display: grid;
  gap: 1rem;
  grid-template-rows: auto 1fr;
  padding: 1rem;
  opacity: .55;
}

.sb-05__cards {
  display: grid;
  grid-template-columns: repeat(3,1fr);
  gap: 1rem;
}

.sb-05__card {
  block-size: 5.5rem;
  border-radius: 12px;
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--line);
}

.sb-05__chart {
  border-radius: 12px;
  background: linear-gradient(180deg, var(--wash), transparent 70%), var(--panel);
  box-shadow: inset 0 0 0 1px var(--line);
}

.sb-05 :focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}
/* light fallback (this demo is dark-first) */

.sb-05[data-theme="light"] {
  --bg: #f5f6fa;
  --shell: #fff;
  --panel: #fff;
  --panel-2: #f3f4f9;
  --ink: #12141c;
  --muted: #6b7080;
  --line: #e5e7f0;
  --acc: #6455f0;
  --acc-2: #0d9488;
  --wash: rgba(100,85,240,.10);
  --ring: #6455f0;
  --shadow: rgba(20,22,40,.2);
  background: radial-gradient(52rem 32rem at 88% -10%, rgba(100,85,240,.10), transparent 68%), var(--bg);
}

.sb-05[data-theme="light"] .sb-05__row:hover {
  background: #f5f6fa;
}

@media (prefers-color-scheme: light) {
  .sb-05:not([data-theme="dark"]) {
    --bg: #f5f6fa;
    --shell: #fff;
    --panel: #fff;
    --panel-2: #f3f4f9;
    --ink: #12141c;
    --muted: #6b7080;
    --line: #e5e7f0;
    --acc: #6455f0;
    --acc-2: #0d9488;
    --wash: rgba(100,85,240,.10);
    --ring: #6455f0;
    --shadow: rgba(20,22,40,.2);
    background: radial-gradient(52rem 32rem at 88% -10%, rgba(100,85,240,.10), transparent 68%), var(--bg);
  }

  .sb-05:not([data-theme="dark"]) .sb-05__row:hover {
    background: #f5f6fa;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sb-05 *,
    .sb-05 *::before,
    .sb-05 *::after {
    animation: none !important;
    transition: none !important;
  }
}

@media (forced-colors: active) {
  .sb-05__field,
    .sb-05__panel,
    .sb-05__shell {
    border: 1px solid CanvasText;
  }

  .sb-05__row[aria-selected="true"] {
    outline: 2px solid Highlight;
  }
}

.sb-05__theme {
  position: absolute;
  inset-block-start: clamp(.75rem,2vw,1.25rem);
  inset-inline-end: clamp(.75rem,2vw,1.25rem);
  z-index: 50;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(0,0,0,.12);
  color: currentColor;
  background: rgba(255,255,255,.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transition: background .25s ease, transform .25s cubic-bezier(.16,1,.3,1), border-color .25s ease;
}

.sb-05[data-theme="dark"] .sb-05__theme {
  background: rgba(20,20,28,.72);
  border-color: rgba(255,255,255,.15);
  color: #fff;
}

@media (prefers-color-scheme: dark) {
  .sb-05:not([data-theme="light"]) .sb-05__theme {
    background: rgba(20,20,28,.72);
    border-color: rgba(255,255,255,.15);
    color: #fff;
  }
}

.sb-05__theme:hover {
  transform: translateY(-1px);
  border-color: rgba(0,0,0,.24);
}

.sb-05[data-theme="dark"] .sb-05__theme:hover,
.sb-05:not([data-theme="light"]) .sb-05__theme:hover {
  border-color: rgba(255,255,255,.3);
}

.sb-05__theme:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

.sb-05__theme svg {
  grid-area: 1/1;
  inline-size: 1.1rem;
  block-size: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sb-05__sun {
  display: none;
}

.sb-05__theme[aria-pressed="true"] .sb-05__sun {
  display: block;
}

.sb-05__theme[aria-pressed="true"] .sb-05__moon {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .sb-05__theme {
    transition: none;
  }

  .sb-05__theme:hover {
    transform: none;
  }
}
```

## JavaScript
```js
(() => {
  const root = document.querySelector('.sb-05');
  if (!root) return;
  const combo = root.querySelector('.sb-05__combo');
  const input = root.querySelector('#sb-05-input');
  const rows = [...root.querySelectorAll('.sb-05__row')];

  const select = (el) => {
    if (!el) return;
    rows.forEach((r) => r.setAttribute('aria-selected', String(r === el)));
    input.setAttribute('aria-activedescendant', el.id);
    el.scrollIntoView({ block: 'nearest' });
  };
  const index = () => rows.findIndex((r) => r.getAttribute('aria-selected') === 'true');

  input.addEventListener('focus', () => input.setAttribute('aria-expanded', 'true'));
  input.addEventListener('blur', () => input.setAttribute('aria-expanded', 'false'));
  input.addEventListener('keydown', (e) => {
    const i = index();
    if (e.key === 'ArrowDown') { e.preventDefault(); select(rows[(i + 1) % rows.length]); }
    if (e.key === 'ArrowUp') { e.preventDefault(); select(rows[(i - 1 + rows.length) % rows.length]); }
    if (e.key === 'Enter') { e.preventDefault(); rows[i] && rows[i].animate([{ scale: '.985' }, { scale: '1' }], 150); }
    if (e.key === 'Escape') { input.blur(); }
  });
  rows.forEach((r) => {
    r.addEventListener('mousemove', () => select(r));
    r.addEventListener('mousedown', (e) => e.preventDefault());   /* keep focus in the field */
  });
  document.addEventListener('keydown', (e) => {
    if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); input.focus(); input.select(); }
  });
})();
(()=>{const r=document.querySelector('.sb-05');if(!r)return;const t=r.querySelector('.sb-05__theme');if(!t)return;const dark=()=>(r.dataset.theme||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'))==='dark';const sync=()=>{t.setAttribute('aria-pressed',String(dark()));t.setAttribute('aria-label',dark()?'Switch to light theme':'Switch to dark theme');};t.addEventListener('click',()=>{r.dataset.theme=dark()?'light':'dark';sync();});matchMedia('(prefers-color-scheme: dark)').addEventListener('change',()=>{if(!r.dataset.theme)sync();});sync();})();
```

How this works

1 — the panel opens without JavaScript. .sb-05__combo:focus-within .sb-05__panel flips opacity, translate and visibility. Because the panel is a child of the same wrapper as the input, clicking a row does not close it mid-click — the classic blur race that breaks JS-driven dropdowns never happens.

2 — JavaScript owns only what CSS cannot express. Two things: the ARIA state, and the roving active option.

const select = (el) => {
  rows.forEach((r) => r.setAttribute('aria-selected', String(r === el)));
  input.setAttribute('aria-activedescendant', el.id);
  el.scrollIntoView({ block:'nearest' });   /* keep it inside the scroll box */
};
input.addEventListener('keydown', (e) => {
  if (e.key === 'ArrowDown'){ e.preventDefault(); select(rows[(i + 1) % rows.length]); }
});

3 — why sections and not one flat list. Grouping is what makes a dashboard search usable: recency, prediction and verbs are three different mental models. Each group is a role="group" with aria-labelledby pointing at its sticky heading, so a screen reader announces "Suggested, 3 items" as you arrow into it, and the headings stay visible while the list scrolls.

4 — shortcut chips. The quick actions expose their real key bindings in <kbd>, styled with a mono stack and font-variant-numeric: tabular-nums so ⌘⇧N and ⌘, stay the same width.

Make it yours

  • Section content is plain markup — swap Recent for your last-viewed API objects, Suggested for a ranked model response, Quick actions for your command registry.
  • Recolour by editing --acc (violet) and --acc-2 (the sparkle teal). Every wash, ring and icon tint derives from those two.
  • To ship it light-first, delete the dark token block from the root and move it under @media (prefers-color-scheme:dark) only.
  • Wire Enter to navigation by reading a data-href on the active row inside the existing keydown branch.
  • Drop the dashboard shell (.sb-05__shell and its children) and keep .sb-05__combo for a standalone field.

Gotchas — read before shipping

  • scrollIntoView({block:'nearest'}) is essential — the default 'start' jumps the panel and, on a page-level scroller, yanks the whole document.
  • Sticky headings inside an overflow:auto panel need a background; a transparent sticky heading lets rows scroll visibly beneath the text.
  • Never trap Tab inside a non-modal dropdown. Escape closes it (this demo blurs the input); Tab must move on naturally.
  • If you also bind ⌘K to focus this field, call preventDefault() — browsers own that chord by default.

Browser support

ChromeSafariFirefoxEdge
111+16.2+121+111+

Floor set by :has(), oklch(), color-mix(), backdrop-filter as this demo is written. The core technique itself goes back further — Chrome 105+.

:focus-within, position:sticky and CSS custom properties work in every current browser. :has() is used for the empty-section rule and is gated. oklch()/color-mix() sit behind @supports with hex fallbacks first. The demo is fully usable with JavaScript disabled — the panel still opens, only roving selection is lost.

Techniques used in this demo

Search CodeFronts

Loading…