Forms
Learn Bootstrap's form styling: .form-control, .form-label, .form-select, .form-check, and building form layouts with the grid.
Introduction
Forms are how users tell your application what they want — logging in, signing up, checking out. Raw HTML form elements look inconsistent across browsers, so Bootstrap provides a set of classes that make text inputs, selects, checkboxes, and radios look clean and consistent everywhere, while staying fully accessible.
- How to style inputs with .form-control and labels with .form-label.
- How to style <select> menus and checkboxes/radios.
- How to lay out multi-field forms with the grid.
- Input groups, sizing, and disabled/readonly fields.
Form Controls
The `.form-control` class is applied to text-based `<input>`, `<textarea>`, and similar elements. It gives them full width by default, consistent padding, a subtle border, and a nice focus glow when clicked into.
<div class="mb-3"> <label for="emailInput" class="form-label">Email address</label> <input type="email" class="form-control" id="emailInput" placeholder="name@example.com"></div><div class="mb-3"> <label for="messageInput" class="form-label">Message</label> <textarea class="form-control" id="messageInput" rows="3"></textarea></div>Click Run to see what this code prints.
Form Labels
Use `.form-label` on a `<label>` element paired with each input via a matching `for`/`id` attribute. This adds consistent bottom margin and font weight, and — critically — keeps the label properly associated with its input for screen readers and click-to-focus behavior.
<label for="nameInput" class="form-label">Full Name</label><input type="text" class="form-control" id="nameInput">Click Run to see what this code prints.
Select Menus
Apply `.form-select` to a `<select>` element to get a custom-styled dropdown arrow and matching border/padding, instead of the browser's inconsistent default select styling.
<label for="countrySelect" class="form-label">Country</label><select class="form-select" id="countrySelect"> <option selected>Choose...</option> <option value="us">United States</option> <option value="in">India</option> <option value="uk">United Kingdom</option></select>Click Run to see what this code prints.
Checkboxes & Radios
Checkboxes and radio buttons use the `.form-check` wrapper, with `.form-check-input` on the `<input>` and `.form-check-label` on the `<label>`. Radios sharing the same `name` attribute behave as a mutually exclusive group, exactly like plain HTML.
<div class="form-check"> <input class="form-check-input" type="checkbox" id="newsletterCheck"> <label class="form-check-label" for="newsletterCheck"> Subscribe to newsletter </label></div>
<div class="form-check"> <input class="form-check-input" type="radio" name="plan" id="planFree" checked> <label class="form-check-label" for="planFree">Free Plan</label></div><div class="form-check"> <input class="form-check-input" type="radio" name="plan" id="planPro"> <label class="form-check-label" for="planPro">Pro Plan</label></div>Click Run to see what this code prints.
Form Layout with Grid
For multi-field forms, combine `.row` and `.col-*` (from the grid system covered earlier) with `.g-3` for consistent gutters, to lay fields out side by side on wider screens while stacking on mobile.
<form> <div class="row g-3"> <div class="col-md-6"> <label for="firstName" class="form-label">First name</label> <input type="text" class="form-control" id="firstName"> </div> <div class="col-md-6"> <label for="lastName" class="form-label">Last name</label> <input type="text" class="form-control" id="lastName"> </div> <div class="col-12"> <button type="submit" class="btn btn-primary">Submit</button> </div> </div></form>Click Run to see what this code prints.
Input Groups
`.input-group` lets you attach text, icons, or buttons directly to the edge of an input — for example, a "$" prefix on a price field, or an "@" prefix on a username field.
<div class="input-group mb-3"> <span class="input-group-text">@</span> <input type="text" class="form-control" placeholder="username"></div>Click Run to see what this code prints.
Sizing Form Controls
Just like buttons, form controls accept `.form-control-lg` or `.form-control-sm` (and `.form-select-lg`/`.form-select-sm`) to adjust height, padding, and font size.
<input class="form-control form-control-sm mb-2" type="text" placeholder="Small input"><input class="form-control mb-2" type="text" placeholder="Default input"><input class="form-control form-control-lg" type="text" placeholder="Large input">Click Run to see what this code prints.
Disabled & Readonly Fields
Add the `disabled` attribute to fully prevent interaction and graying out a field (it also won't be submitted with the form). Use `readonly` instead when the value should still be submitted and readable, just not editable.
<input type="text" class="form-control mb-2" value="Can't touch this" disabled><input type="text" class="form-control" value="Locked but submitted" readonly>Click Run to see what this code prints.
Common Mistakes
- Leaving off the for/id pairing between <label> and <input>, which breaks click-to-focus and accessibility.
- Applying .form-control to a <select> instead of .form-select, which produces broken styling.
- Forgetting .form-check-input / .form-check-label on checkboxes and radios and just styling the wrapper.
- Using disabled when you actually want readonly (disabled fields are excluded from form submission).
Best Practices
- Always pair a visible <label> with every input for accessibility, even if visually hidden with .visually-hidden.
- Use the grid (row/col + g-3) for any form with more than one field per line.
- Group related radios/checkboxes visually and use fieldset/legend for larger forms.
- Prefer semantic input types (email, tel, number) so mobile keyboards adapt automatically.
- Use input groups for units, currency symbols, or icon prefixes instead of custom absolute positioning.
Frequently Asked Questions
No, <form> has no required Bootstrap class — styling is applied to the individual controls (.form-control, .form-select, .form-check) inside it.
Add the .form-switch class to the .form-check wrapper alongside a checkbox input to get Bootstrap's built-in switch styling.
Yes, a .btn placed as a direct child of .input-group will automatically attach to the input's edge, commonly used for search boxes.
Double-check the class name — it's .form-select (not .form-control) for <select> elements in Bootstrap 5.
Key Takeaways
- .form-control styles text inputs and textareas; .form-select styles dropdowns.
- .form-label pairs with an input's id via the label's for attribute.
- Checkboxes/radios use .form-check, .form-check-input, and .form-check-label together.
- The grid system (row/col + g-3) is the standard way to lay out multi-field forms.
- .input-group attaches text, icons, or buttons to an input's edge.
- disabled excludes a field from submission; readonly still submits its value.
Summary
Bootstrap turns plain, browser-inconsistent form elements into clean, aligned, accessible controls with just a handful of classes. Combined with the grid system, you can build anything from a simple search box to a full multi-column registration form. Next, you'll add validation styling so users get immediate visual feedback when a field is filled in incorrectly.