Layout
Stacked, grid, horizontal and inline form layouts.
Bootstrap’s layout docs describe the markup and CSS.
Stacked
Form controls are full width, so fields stack. Space them with a .vstack and a gap, or with margin utilities. Always give <button>s a type, because buttons in a form default to submit.
<div class="vstack gap-3">
<div bsFormField>
<label bsFormLabel>Example label</label>
<input bsFormControl placeholder="Example input placeholder" />
</div>
<div bsFormField>
<label bsFormLabel>Another label</label>
<input bsFormControl placeholder="Another input placeholder" />
</div>
</div>Form grid
Build multi-column forms with the grid. Gutter classes such as .g-3 space rows and columns.
<form class="row g-3">
<div bsFormField class="md:col-6">
<label bsFormLabel>Email</label>
<input type="email" bsFormControl autocomplete="email" />
</div>
<div bsFormField class="md:col-6">
<label bsFormLabel>Password</label>
<input type="password" bsFormControl autocomplete="new-password" />
</div>
<div bsFormField class="col-12">
<label bsFormLabel>Address</label>
<input bsFormControl placeholder="1234 Main St" autocomplete="address-line1" />
</div>
<div bsFormField class="md:col-6">
<label bsFormLabel>City</label>
<input bsFormControl autocomplete="address-level2" />
</div>
<div bsFormField class="md:col-4">
<label bsFormLabel>State</label>
<select bsFormControl>
<option selected>Choose…</option>
<option>…</option>
</select>
</div>
<div bsFormField class="md:col-2">
<label bsFormLabel>Zip</label>
<input bsFormControl autocomplete="postal-code" />
</div>
<div class="col-12">
<div bsFormField>
<input type="checkbox" bsCheck />
<label bsLabel>Check me out</label>
</div>
</div>
<div class="col-12">
<button type="submit" bsButton theme="primary">Sign in</button>
</div>
</form>Horizontal form
Use .row and column classes such as .sm:col-2 to put labels next to controls. Add .col-form-label to labels to center them vertically with their controls, and .col-form-label-sm or .col-form-label-lg to match a control’s size.
<form>
<div class="row mb-3">
<label for="horizontalEmail" class="sm:col-2 col-form-label">Email</label>
<div class="sm:col-10">
<input type="email" bsFormControl id="horizontalEmail" autocomplete="email" />
</div>
</div>
<div class="row mb-3">
<label for="horizontalPassword" class="sm:col-2 col-form-label col-form-label-sm"
>Password</label
>
<div class="sm:col-10">
<input
type="password"
bsFormControl
controlSize="sm"
id="horizontalPassword"
autocomplete="current-password" />
</div>
</div>
<fieldset class="row mb-3">
<legend class="col-form-label sm:col-2 pt-0">Radios</legend>
<div class="sm:col-10">
<div class="form-group">
<div bsFormField class="mb-1">
<input type="radio" bsRadio name="gridRadios" value="option1" checked />
<label bsLabel>First radio</label>
</div>
<div bsFormField class="mb-1">
<input type="radio" bsRadio name="gridRadios" value="option2" />
<label bsLabel>Second radio</label>
</div>
<div bsFormField>
<input type="radio" bsRadio name="gridRadios" value="option3" disabled />
<label bsLabel>Third disabled radio</label>
</div>
</div>
</div>
</fieldset>
<div class="row mb-3">
<div class="sm:col-10 sm:offset-2">
<div bsFormField>
<input type="checkbox" bsCheck />
<label bsLabel>Example checkbox</label>
</div>
</div>
</div>
<button type="submit" bsButton theme="primary">Sign in</button>
</form>Column sizing
Give some columns a size, such as .sm:col-7, and the remaining .cols share the rest.
<div class="row g-3">
<div class="sm:col-7">
<input bsFormControl placeholder="City" aria-label="City" />
</div>
<div class="sm:col">
<input bsFormControl placeholder="State" aria-label="State" />
</div>
<div class="sm:col">
<input bsFormControl placeholder="Zip" aria-label="Zip" />
</div>
</div>Auto-sizing
Use .col-auto so columns only take the space they need. Hide labels visually with .visually-hidden when the layout has no room, so screen readers still announce them.
<form class="row gy-2 gx-3 align-items-center">
<div class="col-auto">
<label class="visually-hidden" for="autoSizingName">Name</label>
<input bsFormControl id="autoSizingName" placeholder="Jane Doe" />
</div>
<div class="col-auto">
<label class="visually-hidden" for="autoSizingUsername">Username</label>
<div bsInputGroup>
<div bsInputGroupText>@</div>
<input bsFormControl id="autoSizingUsername" placeholder="Username" />
</div>
</div>
<div class="col-auto">
<div bsFormField>
<input type="checkbox" bsCheck />
<label bsLabel>Remember me</label>
</div>
</div>
<div class="col-auto">
<button type="submit" bsButton theme="primary">Submit</button>
</div>
</form>Inline forms
Use .lg:row-cols-auto for a form that is one row on large screens and stacks on small ones.
<form class="row lg:row-cols-auto g-3 align-items-center">
<div class="col-12">
<label class="visually-hidden" for="inlineUsername">Username</label>
<div bsInputGroup>
<div bsInputGroupText>@</div>
<input bsFormControl id="inlineUsername" placeholder="Username" />
</div>
</div>
<div class="col-12">
<label class="visually-hidden" for="inlinePreference">Preference</label>
<select bsFormControl id="inlinePreference">
<option selected>Choose…</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
<div class="col-12">
<div bsFormField>
<input type="checkbox" bsCheck />
<label bsLabel>Remember me</label>
</div>
</div>
<div class="col-12">
<button type="submit" bsButton theme="primary">Submit</button>
</div>
</form>