Input Group
v1.0.0Groups labelled native controls with text, icons or buttons.
Search action
Use .input-group-text for a decorative icon or prefix and a native button for actions. Keep the label outside and hide decorative icons.
<label class="form-label" for="groupSearch">Search the documentation</label>
<div class="input-group">
<span class="input-group-text" aria-hidden="true"><!-- Search icon --></span>
<input class="form-control" id="groupSearch" name="search" type="search" />
<button class="btn btn-primary btn-solid" type="button">Search</button>
</div>
Currency and unit suffixes
Add-ons are not labels. Preserve native attributes such as inputmode, min and step.
<label class="form-label" for="groupPrice">Price</label>
<div class="input-group">
<span class="input-group-text" aria-hidden="true">€</span>
<input class="form-control" id="groupPrice" name="price" inputmode="decimal" />
<span class="input-group-text" aria-hidden="true">EUR</span>
</div>
Password reveal
Link the button with aria-controls and synchronize aria-pressed with the input type in application JavaScript.
<label class="form-label" for="groupPassword">Password</label>
<div class="input-group">
<input
class="form-control"
id="groupPassword"
name="password"
type="password"
autocomplete="current-password" />
<button
class="btn btn-primary btn-text"
type="button"
aria-controls="groupPassword"
aria-pressed="false"
aria-label="Show password">
Show password
</button>
</div>
Textarea and select
The group accepts textarea .form-control and native .form-select elements, wrapping when needed.
Sizes
Use .input-group-sm or .input-group-lg to size every item.
Invalid and disabled
Keep validation on the native control with .is-invalid, aria-invalid="true" and aria-describedby. Disable every control in a disabled group.
Right to left
Logical spacing follows document direction without changing source order.
CSS Variables
Override these variables on .input-group or an ancestor. Increase --input-group-control-min-size for earlier wrapping; use 0px for maximum shrinking.
--input-group-bg-color: var(--bg-surface);
--input-group-border-width: var(--border-width);
--input-group-border-color: var(--control-border-color);
--input-group-border-radius: var(--border-radius-lg);
--input-group-box-shadow: none;
--input-group-color: var(--text-color);
--input-group-addon-bg-color: var(--bg-highlight);
--input-group-addon-color: var(--text-muted);
--input-group-inset: var(--spacer-1);
--input-group-gap: var(--spacer-1);
--input-group-item-border-radius: calc(var(--input-group-border-radius) - var(--input-group-inset));
--input-group-padding-y: var(--spacer-1);
--input-group-padding-x: var(--spacer-3);
--input-group-font-size: var(--font-size);
--input-group-control-min-size: 8rem;
--input-group-focus-border-color: var(--primary-hover);
--input-group-focus-outline-width: var(--focus-outline-width);
--input-group-focus-outline-style: var(--focus-outline-style);
--input-group-focus-outline-color: var(--focus-outline-color);
--input-group-focus-outline-offset: var(--focus-offset);
--input-group-invalid-color: var(--error);
--input-group-disabled-text-color: var(--disabled-text-color);
--input-group-disabled-bg-color: var(--disabled-bg-color);
--input-group-disabled-border-color: var(--disabled-border-color);
--input-group-transition-duration: var(--transition-duration);
--input-group-transition-easing: var(--transition-easing);