Form adorn
Decorate inputs with icons, text, and more using a custom wrapper that easily handles styling and positioning.
How it works
The .form-adorn wrapper replicates .form-control styling (border, background, focus states) while using flexbox to position adornments alongside a "ghost input," a form control that has virtually no visual styling. The .form-ghost input inside is transparent and inherits styles from the wrapper.
See the form control documentation for more information on the .form-control and .form-ghost classes.
Example
Wrap an icon and a .form-ghost input inside .form-adorn. Place the adornment before the input in the DOM for start position (left in LTR).
<div class="form-control form-adorn">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#search" /></svg>
</div>
<input type="text" class="form-ghost" placeholder="Search...">
</div> Use .form-adorn-end to position the adornment on the trailing side (keeps DOM order, uses CSS to flip visually):
<div class="form-control form-adorn form-adorn-end">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#envelope" /></svg>
</div>
<input type="email" class="form-ghost" placeholder="you@example.com">
</div> With labels
Add a label outside the .form-adorn wrapper for proper form semantics:
<div>
<label for="searchInput" class="form-label">Search</label>
<div class="form-control form-adorn">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#search" /></svg>
</div>
<input type="text" class="form-ghost" id="searchInput" placeholder="Search...">
</div>
</div>
<div>
<label for="emailInput" class="form-label">Email address</label>
<div class="form-control form-adorn form-adorn-end">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#envelope" /></svg>
</div>
<input type="email" class="form-ghost" id="emailInput" placeholder="you@example.com">
</div>
</div> Text adornments
Use .form-adorn-text for currency symbols, units, domain suffixes, and other text-based adornments. Text adornments auto-size to their content.
<div class="form-control form-adorn">
<span class="form-adorn-text">$</span>
<input type="text" class="form-ghost" placeholder="0.00">
</div>
<div class="form-control form-adorn form-adorn-end">
<span class="form-adorn-text">USD</span>
<input type="text" class="form-ghost" placeholder="Amount">
</div>
<div class="form-control form-adorn">
<span class="form-adorn-text">https://</span>
<input type="text" class="form-ghost" placeholder="example.com">
</div>
<div class="form-control form-adorn form-adorn-end">
<span class="form-adorn-text">@example.com</span>
<input type="text" class="form-ghost" placeholder="username">
</div> Sizing
Use .form-adorn-sm or .form-adorn-lg on the wrapper to adjust sizing.
<div class="form-control form-control-sm form-adorn">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#search" /></svg>
</div>
<input type="text" class="form-ghost" placeholder="Small input">
</div>
<div class="form-control form-adorn">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#search" /></svg>
</div>
<input type="text" class="form-ghost" placeholder="Default input">
</div>
<div class="form-control form-control-lg form-adorn">
<div class="form-adorn-icon">
<svg class="bi" width="16" height="16"><use href="#search" /></svg>
</div>
<input type="text" class="form-ghost" placeholder="Large input">
</div> CSS
Variables
// stylelint-disable-next-line scss/dollar-variable-default
$form-adorn-tokens: defaults(
(
--form-adorn-gap: .375rem,
--form-adorn-icon-size: 1rem,
--form-adorn-icon-color: var(--fg-2),
),
$form-adorn-tokens
);