LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1422 min read

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.

What You Will Learn
  • 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>
What Renders

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">
What Renders

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>
What Renders

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>
What Renders

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>
What Renders

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>
What Renders

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">
What Renders

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>
What Renders

Click Run to see what this code prints.

Common Mistakes

Avoid These 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.

Next Lesson →

Form Validation