Form layout and floating labels
By default Bootstrap fields take the full width and stand one under another. For a long form this is awkward: first and last name, city and postcode belong on one line. Layout uses the same grid as the page, and compact forms have floating labels — the label sits inside the field and shrinks when you type.
Fields in columns
The form gets row g-3, and each field with its label becomes a column. The g-3 gutter separates fields both horizontally and vertically:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<form 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">
<label for="company" class="form-label">Company</label>
<input type="text" class="form-control" id="company">
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Save profile</button>
</div>
</form>From 768 pixels first and last name stand side by side, and "Company" takes the whole row. On a phone all fields are stacked. This is the profile form in the admin dashboard. If you click the button, the preview submits the form and goes blank — bring the example back with "Reset".
A label left of the field
In a horizontal form the label and the field are columns of one row. The label gets col-form-label so that it is vertically centered with the field:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<div class="row mb-3">
<label for="teamName" class="col-sm-3 col-form-label">Team</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="teamName" value="Marketing">
</div>
</div>The label takes 3 parts of 12, the field 9. On screens narrower than 576 pixels the label moves above the field.
Floating labels
A form-floating wrapper: first the field, then the <label>. The field must have a placeholder attribute — Bootstrap uses it to tell whether the field is empty, and the placeholder text itself is not shown:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<div style="max-width: 360px">
<div class="form-floating mb-3">
<input type="email" class="form-control" id="loginEmail" placeholder="name@example.com">
<label for="loginEmail">Email</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="loginPassword" placeholder="Password">
<label for="loginPassword">Password</label>
</div>
<button type="button" class="btn btn-primary w-100">Sign in</button>
</div>The labels sit inside tall fields. Click a field and its label shrinks and moves up, making room for the text. This compact sign-in form looks good on a separate admin dashboard page. form-floating also works with textarea and form-select.
Common mistake
Putting the <label> before the field inside form-floating, or forgetting the placeholder. In both cases the label does not "float": it overlaps the typed text or sits in the wrong place. The order inside the wrapper is always: input first, then label, and the field has a placeholder.