Input Group

v1.0.0

Groups 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.

Enter an amount greater than zero.

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);