Add icons, text, buttons, and helper content to inputs with Bootstrap's native grouping behavior.
Use .input-group when a text input needs a tightly attached prefix, suffix, icon, button, or short addon. Put the editable control and its attached addons inside one group, and keep any visible label outside the group as Bootstrap recommends.
.input-group
label
Keep the input as the primary control. Addons should clarify the value, such as a currency symbol, unit, search icon, domain suffix, or action button; avoid nesting unrelated controls that make the group hard to scan or tab through.
Input groups wrap by default to make validation possible. Apply size classes such as .input-group-sm or .input-group-lg to the group itself, not to each child, and be careful with hidden first or last children because they can affect Bootstrap's joined border radius.
.input-group-sm
.input-group-lg
Place a decorative icon in input-group-text before the input when it clarifies the field's purpose.
input-group-text
1 2 3 4 5 6 7 8 9 10<div class="field w-100"> <label class="form-label" for="icon-start-search">Input</label> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-search" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" id="icon-start-search" type="search" placeholder="Search..." aria-label="Search" aria-describedby="icon-start-search-help"> </div> <div class="field-description form-text" id="icon-start-search-help">Icon positioned at the start.</div> </div>
<div class="field w-100"> <label class="form-label" for="icon-start-search">Input</label> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-search" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" id="icon-start-search" type="search" placeholder="Search..." aria-label="Search" aria-describedby="icon-start-search-help"> </div> <div class="field-description form-text" id="icon-start-search-help">Icon positioned at the start.</div> </div>
Place the addon after the input when the affordance belongs to the trailing edge.
1 2 3 4 5 6 7 8 9 10<div class="field w-100"> <label class="form-label" for="icon-end-password">Input</label> <div class="input-group"> <input class="form-control" id="icon-end-password" type="text" placeholder="Enter password" aria-label="Password" aria-describedby="icon-end-password-help"> <span class="input-group-text"> <i class="lucide lucide-eye-off" data-icon="inline-start" aria-hidden="true"></i> </span> </div> <div class="field-description form-text" id="icon-end-password-help">Icon positioned at the end.</div> </div>
<div class="field w-100"> <label class="form-label" for="icon-end-password">Input</label> <div class="input-group"> <input class="form-control" id="icon-end-password" type="text" placeholder="Enter password" aria-label="Password" aria-describedby="icon-end-password-help"> <span class="input-group-text"> <i class="lucide lucide-eye-off" data-icon="inline-start" aria-hidden="true"></i> </span> </div> <div class="field-description form-text" id="icon-end-password-help">Icon positioned at the end.</div> </div>
Keep a result count in the same surface while the input remains the editable control.
1 2 3 4 5 6 7 8 9<div class="field w-100"> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-search" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" type="search" placeholder="Search..." aria-label="Search results"> <span class="input-group-text">12 results</span> </div> </div>
<div class="field w-100"> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-search" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" type="search" placeholder="Search..." aria-label="Search results"> <span class="input-group-text">12 results</span> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30<div class="field-group w-100"> <div class="field"> <div class="input-group"> <span class="input-group-text">$</span> <input class="form-control" type="text" placeholder="0.00" aria-label="Amount"> <span class="input-group-text">USD</span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text">https://</span> <input class="form-control" type="text" placeholder="example.com" aria-label="Site path"> <span class="input-group-text">.com</span> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="Enter your username" aria-label="Work email"> <span class="input-group-text">@company.com</span> </div> </div> <div class="field"> <div class="input-group"> <textarea class="form-control" rows="2" placeholder="Enter your message" aria-label="Message"></textarea> <div data-align="block-end"> <span class="input-group-text">120 characters left</span> </div> </div> </div> </div>
<div class="field-group w-100"> <div class="field"> <div class="input-group"> <span class="input-group-text">$</span> <input class="form-control" type="text" placeholder="0.00" aria-label="Amount"> <span class="input-group-text">USD</span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text">https://</span> <input class="form-control" type="text" placeholder="example.com" aria-label="Site path"> <span class="input-group-text">.com</span> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="Enter your username" aria-label="Work email"> <span class="input-group-text">@company.com</span> </div> </div> <div class="field"> <div class="input-group"> <textarea class="form-control" rows="2" placeholder="Enter your message" aria-label="Message"></textarea> <div data-align="block-end"> <span class="input-group-text">120 characters left</span> </div> </div> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="https://example.com/moo" aria-label="Profile URL"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="Copy profile URL"> <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div> <div class="field"> <div class="input-group rounded-pill"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="About secure URLs" data-bs-toggle="popover" data-bs-title="Your connection is not secure." data-bs-content="You should not enter sensitive information on this site." data-bs-placement="bottom"> <i class="lucide lucide-info" data-icon="inline-start" aria-hidden="true"></i> </button> <span class="input-group-text">https://</span> <input class="form-control" type="text" aria-label="Secure URL"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="Favorite URL" data-bs-toggle="button" aria-pressed="false"> <i class="lucide lucide-star" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Type to search..." aria-label="Search"> <button class="btn btn-ghost border-0" type="button">Search</button> </div> </div> </div>
<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="https://example.com/moo" aria-label="Profile URL"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="Copy profile URL"> <i class="lucide lucide-copy" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div> <div class="field"> <div class="input-group rounded-pill"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="About secure URLs" data-bs-toggle="popover" data-bs-title="Your connection is not secure." data-bs-content="You should not enter sensitive information on this site." data-bs-placement="bottom"> <i class="lucide lucide-info" data-icon="inline-start" aria-hidden="true"></i> </button> <span class="input-group-text">https://</span> <input class="form-control" type="text" aria-label="Secure URL"> <button class="btn btn-ghost btn-icon border-0" type="button" aria-label="Favorite URL" data-bs-toggle="button" aria-pressed="false"> <i class="lucide lucide-star" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Type to search..." aria-label="Search"> <button class="btn btn-ghost border-0" type="button">Search</button> </div> </div> </div>
Use a single keyboard hint in the trailing addon; avoid splitting one shortcut into separate visual controls.
1 2 3 4 5 6 7 8<div class="field w-100"> <div class="input-group"> <input class="form-control" type="search" placeholder="Search commands..." aria-label="Command search"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div>
<div class="field w-100"> <div class="input-group"> <input class="form-control" type="search" placeholder="Search commands..." aria-label="Command search"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div>
Use an icon-only menu for file actions or a labeled menu when the input action needs a search scope.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="Enter file name" aria-label="File name"> <button class="btn btn-ghost btn-icon-sm border-0" type="button" aria-label="More file actions" data-bs-toggle="dropdown" aria-expanded="false" data-bs-offset="0,8"> <i class="lucide lucide-ellipsis" data-icon="inline-start" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <span>Settings</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Copy path</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Open location</span> </button> </li> </ul> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Enter search query" aria-label="Search query"> <button class="btn btn-ghost btn-sm border-0" type="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-offset="0,8"> Search In... <i class="lucide lucide-chevron-down" data-icon="inline-end" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <span>Documentation</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Blog Posts</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Changelog</span> </button> </li> </ul> </div> </div> </div>
<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="text" placeholder="Enter file name" aria-label="File name"> <button class="btn btn-ghost btn-icon-sm border-0" type="button" aria-label="More file actions" data-bs-toggle="dropdown" aria-expanded="false" data-bs-offset="0,8"> <i class="lucide lucide-ellipsis" data-icon="inline-start" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <span>Settings</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Copy path</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Open location</span> </button> </li> </ul> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Enter search query" aria-label="Search query"> <button class="btn btn-ghost btn-sm border-0" type="button" data-bs-toggle="dropdown" aria-expanded="false" data-bs-offset="0,8"> Search In... <i class="lucide lucide-chevron-down" data-icon="inline-end" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <span>Documentation</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Blog Posts</span> </button> </li> <li> <button class="dropdown-item" type="button"> <span>Changelog</span> </button> </li> </ul> </div> </div> </div>
Use compact loading indicators inside addons when the input value is waiting on async work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Searching..." aria-label="Search workspace"> <span class="input-group-text px-2"> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Searching workspace</span> </div> </span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text gap-2"> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Processing import</span> </div> <span>Processing...</span> </span> <input class="form-control" type="text" value="Import queue" readonly aria-label="Processing import"> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="text" value="Draft settings" readonly aria-label="Saving changes"> <span class="input-group-text gap-2"> <span>Saving...</span> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Saving changes</span> </div> </span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-refresh-cw" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" type="text" value="Refreshing data..." readonly aria-label="Refreshing data"> <span class="input-group-text gap-2"> <span>Please wait...</span> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Refreshing data</span> </div> </span> </div> </div> </div>
<div class="field-group w-100"> <div class="field"> <div class="input-group"> <input class="form-control" type="search" placeholder="Searching..." aria-label="Search workspace"> <span class="input-group-text px-2"> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Searching workspace</span> </div> </span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text gap-2"> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Processing import</span> </div> <span>Processing...</span> </span> <input class="form-control" type="text" value="Import queue" readonly aria-label="Processing import"> </div> </div> <div class="field"> <div class="input-group"> <input class="form-control" type="text" value="Draft settings" readonly aria-label="Saving changes"> <span class="input-group-text gap-2"> <span>Saving...</span> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Saving changes</span> </div> </span> </div> </div> <div class="field"> <div class="input-group"> <span class="input-group-text"> <i class="lucide lucide-refresh-cw" data-icon="inline-start" aria-hidden="true"></i> </span> <input class="form-control" type="text" value="Refreshing data..." readonly aria-label="Refreshing data"> <span class="input-group-text gap-2"> <span>Please wait...</span> <div class="spinner spinner-sm" role="status"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> <span class="visually-hidden">Refreshing data</span> </div> </span> </div> </div> </div>
Place a label-like addon above an input or textarea while keeping the control focusable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18<div class="field-group w-100"> <div class="field"> <div class="input-group"> <div data-align="block-start"> <label class="input-group-text" for="block-start-input">Full Name</label> </div> <input class="form-control" id="block-start-input" type="text" placeholder="Enter your name" aria-label="Display name"> </div> </div> <div class="field"> <div class="input-group"> <div data-align="block-start"> <label class="input-group-text" for="block-start-textarea">script.js</label> </div> <textarea class="form-control" id="block-start-textarea" rows="3" placeholder="console.log('Hello, world!');" aria-label="Code snippet"></textarea> </div> </div> </div>
<div class="field-group w-100"> <div class="field"> <div class="input-group"> <div data-align="block-start"> <label class="input-group-text" for="block-start-input">Full Name</label> </div> <input class="form-control" id="block-start-input" type="text" placeholder="Enter your name" aria-label="Display name"> </div> </div> <div class="field"> <div class="input-group"> <div data-align="block-start"> <label class="input-group-text" for="block-start-textarea">script.js</label> </div> <textarea class="form-control" id="block-start-textarea" rows="3" placeholder="console.log('Hello, world!');" aria-label="Code snippet"></textarea> </div> </div> </div>
Place a unit below the input when the supporting content belongs to the field.
1 2 3 4 5 6 7 8<div class="field w-100"> <div class="input-group"> <input class="form-control" id="block-end-input-control" type="text" placeholder="Enter amount" aria-label="Amount"> <div data-align="block-end"> <label class="input-group-text flex-grow-1" for="block-end-input-control">USD</label> </div> </div> </div>
<div class="field w-100"> <div class="input-group"> <input class="form-control" id="block-end-input-control" type="text" placeholder="Enter amount" aria-label="Amount"> <div data-align="block-end"> <label class="input-group-text flex-grow-1" for="block-end-input-control">USD</label> </div> </div> </div>
Keep a counter and action below the textarea when both belong to the field.
1 2 3 4 5 6 7 8 9<div class="field w-100"> <div class="input-group"> <textarea class="form-control" id="block-end-textarea-control" rows="3" placeholder="Write a comment..." aria-label="Comment"></textarea> <div class="d-flex align-items-center justify-content-between" data-align="block-end"> <label class="input-group-text flex-grow-1" for="block-end-textarea-control">0/280</label> <button class="btn btn-primary" type="button">Post</button> </div> </div> </div>
<div class="field w-100"> <div class="input-group"> <textarea class="form-control" id="block-end-textarea-control" rows="3" placeholder="Write a comment..." aria-label="Comment"></textarea> <div class="d-flex align-items-center justify-content-between" data-align="block-end"> <label class="input-group-text flex-grow-1" for="block-end-textarea-control">0/280</label> <button class="btn btn-primary" type="button">Post</button> </div> </div> </div>
Combine a textarea and action in one Bootstrap input group.
1 2 3 4 5 6 7 8<div class="field w-100"> <div class="input-group"> <textarea class="form-control" rows="4" placeholder="Write a message..." aria-label="Custom message"></textarea> <div class="justify-content-end" data-align="block-end"> <button class="btn btn-primary" type="button">Submit</button> </div> </div> </div>
<div class="field w-100"> <div class="input-group"> <textarea class="form-control" rows="4" placeholder="Write a message..." aria-label="Custom message"></textarea> <div class="justify-content-end" data-align="block-end"> <button class="btn btn-primary" type="button">Submit</button> </div> </div> </div>
Use one compact search control across Arabic and Hebrew RTL examples, with English as the LTR comparison.
1 2 3 4 5 6 7 8 9 10<div dir="rtl"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-arabic" type="search" placeholder="ابحث داخل المحادثة" aria-label="بحث"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
<div dir="rtl"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-arabic" type="search" placeholder="ابحث داخل المحادثة" aria-label="بحث"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
1 2 3 4 5 6 7 8 9 10<div dir="rtl"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-hebrew" type="search" placeholder="חפש בצ'אנל" aria-label="חיפוש"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
<div dir="rtl"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-hebrew" type="search" placeholder="חפש בצ'אנל" aria-label="חיפוש"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
1 2 3 4 5 6 7 8 9 10<div dir="ltr"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-english" type="search" placeholder="Search the channel" aria-label="Search"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
<div dir="ltr"> <div class="field w-100"> <div class="input-group"> <input class="form-control" id="input-group-rtl-english" type="search" placeholder="Search the channel" aria-label="Search"> <span class="input-group-text"> <kbd>⌘K</kbd> </span> </div> </div> </div>
For more addon combinations, see the Bootstrap Input group documentation.
No matching pages.
Restore the default appearance.