Input Group

A Tailwind CSS input group component for decorating inputs with icons, buttons, or text addons.

https://
<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
      <input class="input" placeholder="Search" />
    </div>
    <div class="input-group">
      <input
        class="input"
        type="password"
        placeholder="Password"
        value="supersecret"
      />
      <button
        class="input-group-btn-icon"
        type="button"
        aria-label="Show password"
      >
        <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"><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>
      </button>
    </div>
    <div class="input-group">
      <span class="input-group-text">https://</span>
      <input class="input" placeholder="example.com" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="Search" />
      <button class="input-group-btn" type="button">Go</button>
    </div>
  </div>
</div>

Icons

Use input-group-icon for a non-interactive icon overlay inside the input.

<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
      <input class="input" placeholder="Leading icon" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="Trailing icon" />
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
    </div>
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"/><rect x="2" y="4" width="20" height="16" rx="2"/></svg>
      </span>
      <input class="input" type="email" placeholder="Email" />
      <span class="input-group-icon">
        <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"><path d="M20 6 9 17l-5-5"/></svg>
      </span>
    </div>
  </div>
</div>

Icon buttons

Use input-group-btn-icon for interactive icon buttons like a password toggle or clear action. It overlays the input the same way as input-group-icon.

<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <button class="input-group-btn-icon" type="button" aria-label="Menu">
        <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"><path d="M4 5h16"/><path d="M4 12h16"/><path d="M4 19h16"/></svg>
      </button>
      <input class="input" placeholder="Leading icon button" />
    </div>
    <div class="input-group">
      <input
        class="input"
        type="password"
        placeholder="Password"
        value="supersecret"
      />
      <button
        class="input-group-btn-icon"
        type="button"
        aria-label="Show password"
      >
        <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"><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>
      </button>
    </div>
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
      <input class="input" placeholder="Search" />
      <button class="input-group-btn-icon" type="button" aria-label="Clear">
        <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"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
      </button>
    </div>
  </div>
</div>

Text addons

Use input-group-text for text prefixes, suffixes, or units. It sits next to the input as a separate pill with a muted background.

https://
@company.com
$ USD
<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <span class="input-group-text">https://</span>
      <input class="input" placeholder="example.com" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="username" />
      <span class="input-group-text">@company.com</span>
    </div>
    <div class="input-group">
      <span class="input-group-text">$</span>
      <input class="input" placeholder="0.00" />
      <span class="input-group-text">USD</span>
    </div>
  </div>
</div>

Button addons

Use input-group-btn for a full button that sits next to the input.

<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <button class="input-group-btn" type="button">Search</button>
      <input class="input" placeholder="Leading button" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="Trailing button" />
      <button class="input-group-btn" type="button">Go</button>
    </div>
    <div class="input-group">
      <button class="input-group-btn" type="button">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
        Search
      </button>
      <input class="input" placeholder="Leading button with icon" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="Trailing button with icon" />
      <button class="input-group-btn" type="button">
        Go
        <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"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
      </button>
    </div>
  </div>
</div>

Invalid

Add aria-invalid="true" to the input to show an error state. Adjacent addons automatically mirror the destructive border.

https://
<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
      <input
        class="input"
        placeholder="Invalid with icon"
        aria-invalid="true"
      />
    </div>
    <div class="input-group">
      <input
        class="input"
        type="password"
        placeholder="Invalid with icon button"
        value="bad"
        aria-invalid="true"
      />
      <button
        class="input-group-btn-icon"
        type="button"
        aria-label="Show password"
      >
        <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"><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>
      </button>
    </div>
    <div class="input-group">
      <span class="input-group-text">https://</span>
      <input
        class="input"
        placeholder="Invalid with text"
        aria-invalid="true"
      />
    </div>
    <div class="input-group">
      <input
        class="input"
        placeholder="Invalid with button"
        aria-invalid="true"
      />
      <button class="input-group-btn" type="button">Go</button>
    </div>
  </div>
</div>

Disabled

Add disabled to the input. Addons inside the group dim automatically.

https://
<div class="w-full max-w-xs">
  <div class="field-group">
    <div class="input-group">
      <span class="input-group-icon">
        <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
      </span>
      <input class="input" placeholder="Disabled with icon" disabled="" />
    </div>
    <div class="input-group">
      <input
        class="input"
        type="password"
        placeholder="Disabled with icon button"
        value="supersecret"
        disabled=""
      />
      <button
        class="input-group-btn-icon"
        type="button"
        aria-label="Show password"
        disabled=""
      >
        <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"><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>
      </button>
    </div>
    <div class="input-group">
      <span class="input-group-text">https://</span>
      <input class="input" placeholder="Disabled with text" disabled="" />
    </div>
    <div class="input-group">
      <input class="input" placeholder="Disabled with button" disabled="" />
      <button class="input-group-btn" type="button" disabled="">Go</button>
    </div>
  </div>
</div>

How it works

Input group uses two different patterns depending on what you're adding:

  • Icons and icon buttons (input-group-icon, input-group-btn-icon) are positioned absolutely inside the input. The input gets extra padding so text doesn't collide with them.
  • Text and button addons (input-group-text, input-group-btn) sit next to the input as a separate pill, sharing a seam with the input's border.

Structure

Wrap an .input with one or more addons inside an .input-group container:

<div class="input-group">
  <span class="input-group-icon">
    <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"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
  </span>
  <input class="input" placeholder="Search..." />
</div>

You can combine icon overlays with text or button addons:

<div class="input-group">
  <span class="input-group-text">https://</span>
  <input class="input" placeholder="example" />
  <button class="input-group-btn-icon" type="button" aria-label="Clear">
    <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"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
  </button>
</div>

Class reference

ClassDescription
input-groupContainer for grouped input
input-group-iconNon-interactive icon positioned inside the input
input-group-btn-iconInteractive icon button positioned inside the input
input-group-textText pill addon sitting next to the input (prefix/suffix)
input-group-btnFull button addon sitting next to the input