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.

Don't have an account? Sign up
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>

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.

Gender
Cancel
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>
Up next
Form validation

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.