Input Groups
A Bootstrap 4 input group attaches text, an icon, or a button to the side of a
form control — a currency symbol, a unit suffix, a search button. The wrapper class is
.input-group, but Bootstrap 4's markup requires an extra layer that later got
simplified: any prepended or appended content must sit inside its own
.input-group-prepend or .input-group-append wrapper <div>,
with .input-group-text nested one level deeper inside that. We'll build two real
examples for TrailMap, our hiking-trail directory app: a distance input with a
"mi" suffix, and a trail search box with an attached button.
The Required Structure: Prepend/Append Wrapper Divs
Every input group starts with .input-group on the outer <div>,
with the <input> as a direct child. Text or icons added before or after the
input cannot sit directly inside .input-group — each one needs its own
.input-group-prepend (before the input) or .input-group-append (after
it) wrapper, and .input-group-text goes inside that wrapper.
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input type="text" class="form-control">
</div>
.input-group-prepend/.input-group-append wrappers entirely — a genuine
structural simplification. In Bootstrap 5, .input-group-text can sit as a direct
child of .input-group with no wrapper <div> around it at all.
Copying a Bootstrap 5 input-group example into a Bootstrap 4 page (or vice versa) without adding
or removing that wrapper is a common source of broken-looking input groups.Worked Example: TrailMap's Distance Input with a "mi" Suffix
A numeric distance field with the unit appended after the input, using
.input-group-append:
<label for="trailDistance">Max distance</label>
<div class="input-group mb-3">
<input type="number" id="trailDistance" class="form-control" placeholder="5">
<div class="input-group-append">
<span class="input-group-text">mi</span>
</div>
</div>
Worked Example: TrailMap Search Box with an Attached Button
An appended element doesn't have to be plain text — a <button> works
inside .input-group-append just as well, letting you build a search box with the
submit button visually fused to the field:
<div class="input-group">
<input type="search" class="form-control" placeholder="Search trails by name..." aria-label="Search trails">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button">
<i class="fa fa-search"></i> Search
</button>
</div>
</div>
You can also prepend and append at the same time — for example a currency symbol
before a price field and ".00" after it — by combining a .input-group-prepend and
a .input-group-append around the same <input>.
!important and learn
the proper way to recolor TrailMap in Sass Customization.