Form layout
Structure your forms with form layout options, from inline to horizontal to custom grid implementations.
Create amazing Typeform-like forms and pages just by writing Markdown!
Utilities #
Margin utilities are the easiest way to add some structure to forms. They provide basic grouping of labels, controls, optional form text, and form validation messaging. We recommend sticking to margin-bottom
utilities, and using a single direction throughout the form for consistency.
You can build your forms with <fieldset>
, <div>
, or nearly any other element.
HTML
<form>
<div class="mb-3">
<label class="form-label" for="username">Username</label>
<input type="text" class="form-control" id="username" required placeholder="Username">
</div>
<div class="mb-3">
<label class="form-label" for="password">Password</label>
<input type="password" class="form-control" id="password" required placeholder="Password">
</div>
<div class="mb-3 pb-3 border-bottom">
<button type="submit" class="btn btn-primary w-100">Sign in</button>
</div>
<div class="text-center text-body-secondary">
Don't have an account? <a href="#">Sign up</a>
</div>
</form>
Information
Please note, all forms are block-level and will take up the full width of the parent container. In the example above, the form has been placed inside a container with the class.specific-w-300
.
Form grid #
You can use the grid system along with gutters to create more complex layouts for your forms.
HTML
<form class="row g-3">
<div class="col-sm-6">
<label for="first-name" class="form-label">First name</label>
<input type="text" class="form-control" id="first-name" placeholder="First name" required>
</div>
<div class="col-sm-6">
<label for="last-name" class="form-label">Last name</label>
<input type="text" class="form-control" id="last-name" placeholder="Last name" required>
</div>
<div class="col-12">
<label for="address-1" class="form-label">Address</label>
<input type="text" class="form-control" id="address-1" placeholder="Street and number, block, etc." required>
</div>
<div class="col-12">
<label for="address-2" class="form-label">Address 2</label>
<input type="text" class="form-control" id="address-2" placeholder="Apartment, studio, or floor">
</div>
<div class="col-sm-6">
<label for="city" class="form-label">City</label>
<input type="text" class="form-control" id="city" placeholder="City">
</div>
<div class="col-sm-4">
<label for="state" class="form-label">State</label>
<select id="state" class="form-select">
<option selected>Choose...</option>
<option>...</option>
</select>
</div>
<div class="col-sm-2">
<label for="zip" class="form-label">Zip</label>
<input type="text" class="form-control" id="zip" placeholder="Zip">
</div>
<div class="d-flex align-items-center">
<div class="form-check mb-0">
<input type="checkbox" class="form-check-input" id="agree-to-terms" value="" required>
<label class="form-check-label" for="agree-to-terms">I agree to the terms</label>
</div>
<button type="submit" class="btn btn-primary ms-auto">Submit</button>
</div>
</form>
Horizontal form #
Create horizontal forms with the grid by adding the .row
class to form groups and using the .col-*-*
classes to specify the width of your labels and controls. Be sure to add .col-form-label
to your <label>
elements as well so they're vertically centered with their associated form controls.
At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we've removed the padding-top
on our stacked radio inputs label to better align the text baseline.
Sign up
Please fill out the following form to sign up.
HTML
<form>
<div class="row mb-3">
<label for="full-name-2" class="col-sm-3 col-form-label mb-1 mb-sm-0">Full name</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="full-name-2" placeholder="Full name">
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-sm-3 col-form-label mb-1 mb-sm-0">Email</label>
<div class="col-sm-9">
<input type="email" class="form-control" id="email" placeholder="Email">
</div>
</div>
<div class="row mb-3">
<label for="password-2" class="col-sm-3 col-form-label mb-1 mb-sm-0">Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="password-2" placeholder="Password">
</div>
</div>
<fieldset class="row mb-3">
<legend class="col-form-label mb-1 mb-sm-0 col-sm-3 pt-0">Gender</legend>
<div class="col-sm-9">
<div class="form-check">
<input class="form-check-input" type="radio" name="gender" id="male" value="male" checked>
<label class="form-check-label" for="male">Male</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="gender" id="female" value="female">
<label class="form-check-label" for="female">Female</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="gender" id="other" value="other">
<label class="form-check-label" for="other">Other</label>
</div>
</div>
</fieldset>
<div class="row mb-3">
<div class="col-sm-9 ms-auto">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="agree-to-terms-2">
<label class="form-check-label" for="agree-to-terms-2">I agree to the <a href="#">Terms & Conditions</a></label>
</div>
</div>
</div>
<div class="text-end">
<a href="#" class="btn btn-secondary">Cancel</a>
<button type="submit" class="btn btn-primary">Sign up</button>
</div>
</form>
Horizontal form label sizing #
Be sure to use .col-form-label-sm
or .col-form-label-lg
to your <label>
and <legend>
elements to correctly follow the size of .form-control-sm
and .form-control-lg
.
HTML
<div class="row mb-2 mb-sm-3">
<label for="small-col-form-label" class="col-sm-3 col-form-label col-form-label-sm mb-1 mb-sm-0">Label</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-sm" id="small-col-form-label" placeholder="Placeholder">
</div>
</div>
<div class="row mb-2 mb-sm-3">
<label for="col-form-label" class="col-sm-3 col-form-label mb-1 mb-sm-0">Label</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="col-form-label" placeholder="Placeholder">
</div>
</div>
<div class="row">
<label for="large-col-form-label" class="col-sm-3 col-form-label col-form-label-lg mb-1 mb-sm-0">Label</label>
<div class="col-sm-9">
<input type="text" class="form-control form-control-lg" id="large-col-form-label" placeholder="Placeholder">
</div>
</div>
Column sizing #
As shown in the previous example, our grid system allows you to place any number of .col
containers within a .row
. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining .col
containers equally split the rest, with specific column classes like .col-sm-7
.
HTML
<div class="row g-3">
<div class="col-sm-7">
<input type="text" class="form-control" placeholder="City" aria-label="City">
</div>
<div class="col-sm">
<input type="text" class="form-control" placeholder="State" aria-label="State">
</div>
<div class="col-sm">
<input type="text" class="form-control" placeholder="Zip" aria-label="Zip">
</div>
</div>
Auto-sizing #
You can use .col-auto
/ .col-{breakpoint}-auto
so that the columns only take up as much space as needed. Put another way, the column sizes itself based on the contents. Moreover, adding .align-items-center
to the .row
will vertically center the contents as well.
HTML
<form class="row g-3 align-items-center">
<div class="col-sm-auto">
<label class="visually-hidden" for="full-name">Full name</label>
<input type="text" class="form-control" id="full-name" placeholder="Full name">
</div>
<div class="col-sm-auto">
<label class="visually-hidden" for="username-2">Username</label>
<div class="input-group">
<div class="input-group-text">@</div>
<input type="text" class="form-control" id="username-2" placeholder="Username">
</div>
</div>
<div class="col-sm-auto">
<label class="visually-hidden" for="preference">Preference</label>
<select class="form-select" id="preference">
<option selected>Choose...</option>
<option>...</option>
</select>
</div>
<div class="col-sm-auto">
<div class="form-check mb-0">
<input class="form-check-input" type="checkbox" id="remember-me">
<label class="form-check-label" for="remember-me">Remember me</label>
</div>
</div>
<div class="col-sm-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Inline forms #
Use the .row-cols-*
classes to create responsive horizontal layouts. On narrow mobile viewports, the .col-12
helps stack the form controls and more.
HTML
<form class="row row-cols-sm-auto g-3">
<div class="col-12">
<label class="visually-hidden" for="email-2">Email</label>
<input type="email" class="form-control" id="email-2" placeholder="Email">
</div>
<div class="col-12">
<label class="visually-hidden" for="password-3">Password</label>
<input type="password" class="form-control" id="password-3" placeholder="Password">
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Sign in</button>
</div>
</form>
Help us grow
Our main goal is to make Halfmoon the go-to framework for building websites, dashboards and tools. If you believe in our mission, consider becoming a sponsor and help us grow.
You can email us directly if you have any queries. We are always happy to answer.
Subscribe for updates
We will notify you when the framework gets a substantial update. No spam ever.
Follow us on Twitter so that you can stay updated that way.