HTMX UI
Esc

    Type to search pages and sections.

    You're viewing the docs for v0.1.
    The latest version is next. Go to this page in next.

    Components

    Input group

    Icons, text, buttons, menus and spinners inside an input's border, on either side, above or below.

    View .md
    12 results
    html
    <div class="input-group max-w-sm">
      <input class="input" type="search" placeholder="Search…" aria-label="Search" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg></span>
      <span class="input-group-addon input-group-addon-inline-end">12 results</span>
    </div>

    Usage#

    • Wrap a .input, .textarea or .select in .input-group. The group draws the border and the focus ring; the control drops its own.
    • Add each addon as a .input-group-addon. Put addons after the control in the source. CSS places them, so Tab reaches the control first.
    • States come from the control: aria-invalid="true" turns the whole group red and disabled fades it.

    Align#

    An addon goes at the inline start by default. .input-group-addon-inline-end puts it at the end, .input-group-addon-block-start above the control and .input-group-addon-block-end below it.

    Billed in USD
    html
    <div class="input-group max-w-sm">
      <input class="input" placeholder="Inline start" aria-label="Inline start" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg></span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" type="password" placeholder="Inline end" aria-label="Password" />
      <span class="input-group-addon input-group-addon-inline-end"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg></span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" id="ig-block-start" placeholder="Block start" />
      <label class="input-group-addon input-group-addon-block-start" for="ig-block-start">Full name</label>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" placeholder="Block end" aria-label="Amount" />
      <span class="input-group-addon input-group-addon-block-end"><span class="input-group-text">Billed in USD</span></span>
    </div>

    Icons and text#

    Addons hold icons, text or both. .input-group-text styles plain text inside a busier addon.

    https:// .com
    $ USD
    html
    <div class="input-group max-w-sm">
      <input class="input" type="email" placeholder="you@example.com" aria-label="Email" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" placeholder="example.com" aria-label="Website" />
      <span class="input-group-addon">https://</span>
      <span class="input-group-addon input-group-addon-inline-end">.com</span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" type="number" placeholder="0.00" aria-label="Price" />
      <span class="input-group-addon">$</span>
      <span class="input-group-addon input-group-addon-inline-end">USD</span>
    </div>

    Buttons#

    Buttons inside an addon shrink to fit (24px tall). Use any variant; ghost and secondary sit most naturally.

    html
    <div class="input-group max-w-sm">
      <input class="input" value="https://htmx-ui.dev/r/3f9a" readonly aria-label="Share link" />
      <span class="input-group-addon input-group-addon-inline-end">
        <button class="btn btn-ghost btn-icon" aria-label="Copy"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg></button>
      </span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" type="search" placeholder="Search the docs…" aria-label="Search" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg></span>
      <span class="input-group-addon input-group-addon-inline-end">
        <button class="btn btn-secondary">Search</button>
      </span>
    </div>

    Badges#

    bug ui
    html
    <div class="input-group max-w-sm">
      <input class="input" placeholder="Add a label…" aria-label="Labels" />
      <span class="input-group-addon">
        <span class="badge badge-info">bug</span>
        <span class="badge badge-secondary">ui</span>
      </span>
    </div>

    A dropdown in an addon, for picking a unit or scope.

    html
    <div class="input-group max-w-sm">
      <input class="input" placeholder="Search…" aria-label="Search" />
      <span class="input-group-addon input-group-addon-inline-end">
        <span class="dropdown" data-dropdown>
          <button class="btn btn-ghost" data-dropdown-trigger aria-haspopup="menu" aria-expanded="false">All files <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
          <span class="dropdown-menu dropdown-menu-end" role="menu" hidden>
            <button class="dropdown-item" role="menuitem">All files</button>
            <button class="dropdown-item" role="menuitem">Pages</button>
            <button class="dropdown-item" role="menuitem">Components</button>
          </span>
        </span>
      </span>
    </div>

    Spinner#

    A spinner shows work in progress. With .htmx-indicator it appears only while a request runs: type below to search the mock server.

    html
    <div class="input-group max-w-sm">
      <input class="input" type="search" placeholder="Saving…" disabled aria-label="Saving" />
      <span class="input-group-addon input-group-addon-inline-end"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="spinner" role="status" aria-label="Loading"><path d="M21 12a9 9 0 1 1-6.22-8.56"/></svg></span>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" type="search" name="q" placeholder="Search…" aria-label="Search"
             hx-get="/api/echo" hx-trigger="input changed delay:300ms" hx-target="#ig-search-result" hx-indicator="#ig-search-spinner" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg></span>
      <span class="input-group-addon input-group-addon-inline-end"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" id="ig-search-spinner" class="spinner htmx-indicator" role="status" aria-label="Searching"><path d="M21 12a9 9 0 1 1-6.22-8.56"/></svg></span>
    </div>
    <p id="ig-search-result" class="muted text-sm" aria-live="polite"></p>

    Textarea#

    Block addons above or below a textarea make a compose box. A border-t or border-b utility on the addon draws a divider.

    button.css 52% used
    html
    <div class="input-group max-w-md">
      <textarea class="textarea" placeholder="Ask, search or chat…" aria-label="Prompt"></textarea>
      <span class="input-group-addon input-group-addon-block-start border-b"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4M10 9H8M16 13H8M16 17H8"/></svg> <span class="input-group-text">button.css</span></span>
      <span class="input-group-addon input-group-addon-block-end">
        <button class="btn btn-outline btn-icon btn-rounded" aria-label="Attach"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M5 12h14M12 5v14"/></svg></button>
        <span class="input-group-text ms-auto">52% used</span>
        <button class="btn btn-primary btn-icon btn-rounded" aria-label="Send"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/></svg></button>
      </span>
    </div>

    States#

    @

    Usernames can't contain spaces.

    html
    <div class="field max-w-sm">
      <label class="field-label" for="ig-invalid">Username</label>
      <div class="input-group">
        <input class="input" id="ig-invalid" value="ada lovelace" aria-invalid="true" aria-describedby="ig-invalid-msg" />
        <span class="input-group-addon">@</span>
      </div>
      <p class="field-error" id="ig-invalid-msg">Usernames can't contain spaces.</p>
    </div>
    <div class="input-group max-w-sm">
      <input class="input" placeholder="Disabled" disabled aria-label="Disabled" />
      <span class="input-group-addon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4" aria-hidden="true"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg></span>
    </div>

    Reference#

    ClassDescription
    .input-groupBorder and focus ring around a control and its addons.
    .input-group-addonAddon at the inline start. Holds icons, text, badges, buttons, menus or spinners.
    .input-group-addon-inline-endAddon at the end of the row.
    .input-group-addon-block-startFull-width addon above the control.
    .input-group-addon-block-endFull-width addon below the control.
    .input-group-textPlain muted text inside an addon.