Skip to main contentSkip to docs navigation

Form Layout

Organize form fields with structured layouts using spacing utilities, grid systems, and responsive patterns.

Overview

Chassis CSS provides multiple layout options for organizing form elements. Since Chassis CSS applies display: block and width: 100% to form inputs by default, forms naturally stack vertically. Various layout patterns are available using the classes and techniques described below.

Every group of form fields should reside in a <form> element. While Chassis CSS doesn't apply default styling to the <form> element itself, it's important to use proper semantic HTML:

  • Always specify button types within forms (type="submit", type="button", etc.) as browsers default to type="submit"
  • Use the <fieldset> and <legend> elements to group related form controls
  • Include appropriate ARIA attributes and labels for accessibility
  • For advanced form requirements, consult the MDN form documentation

Spacing utilities

The simplest way to add structure to forms is with margin and padding utilities. These utilities provide consistent spacing between form elements, including labels, controls, help text, and validation messages.

For consistency, Chassis CSS recommends:

  • Using margin-bottom utilities (mb-*) for vertical spacing
  • Applying the same spacing size throughout a single form
  • Using the medium spacing value as a default starting point
HTML
<div class="mb-medium">
  <label for="formGroupExampleInput" class="form-label">Example label</label>
  <input type="text" class="form-input" id="formGroupExampleInput" placeholder="Example input placeholder">
</div>
<div class="mb-medium">
  <label for="formGroupExampleInput2" class="form-label">Another label</label>
  <input type="text" class="form-input" id="formGroupExampleInput2" placeholder="Another input placeholder">
</div>

Grid-based layouts

Chassis CSS's grid system provides powerful options for creating complex form layouts with multiple columns, varied widths, and precise alignment control. The grid system offers several key advantages for form layouts:

  • Responsive layouts that adapt to different screen sizes
  • Flexible column configurations that can be mixed and matched
  • Consistent spacing through the gutter system
  • Vertical alignment control for aligning form elements
  • Nesting capabilities for complex form structures

Note: Grid-based form layouts require the $enable-grid-classes Sass variable to be enabled (enabled by default).

Basic grid layout

Use the .row and .col classes to create evenly-spaced columns within a form:

HTML
<div class="row">
  <div class="col">
    <input type="text" class="form-input" placeholder="First name" aria-label="First name">
  </div>
  <div class="col">
    <input type="text" class="form-input" placeholder="Last name" aria-label="Last name">
  </div>
</div>

Grid gutters

Control the spacing between columns by applying gutter modifier classes. Gutters provide consistent spacing between form elements and help create visual separation in dense layouts. The gutter system offers:

  • Horizontal gutters with .gx-* classes
  • Vertical gutters with .gy-* classes
  • Combined gutters with .g-* classes for both directions
  • Responsive variants that adapt to different viewports

For form layouts, medium-sized gutters (.g-medium) often provide the optimal spacing.

HTML
<div class="row g-medium">
  <div class="col">
    <input type="text" class="form-input" placeholder="First name" aria-label="First name">
  </div>
  <div class="col">
    <input type="text" class="form-input" placeholder="Last name" aria-label="Last name">
  </div>
</div>

Complex grid layouts

Combine grid columns with different widths to create sophisticated form layouts:

HTML
<form class="row g-medium">
  <div class="medium:col-6">
    <label for="inputEmail4" class="form-label">Email</label>
    <input type="email" class="form-input" id="inputEmail4">
  </div>
  <div class="medium:col-6">
    <label for="inputPassword4" class="form-label">Password</label>
    <input type="password" autocomplete="current-password" class="form-input" id="inputPassword4">
  </div>
  <div class="col-12">
    <label for="inputAddress" class="form-label">Address</label>
    <input type="text" class="form-input" id="inputAddress" placeholder="1234 Main St">
  </div>
  <div class="col-12">
    <label for="inputAddress2" class="form-label">Address 2</label>
    <input type="text" class="form-input" id="inputAddress2" placeholder="Apartment, studio, or floor">
  </div>
  <div class="medium:col-6">
    <label for="inputCity" class="form-label">City</label>
    <input type="text" class="form-input" id="inputCity">
  </div>
  <div class="medium:col-4">
    <label for="inputState" class="form-label">State</label>
    <select id="inputState" class="form-input">
      <option value="" selected>Choose...</option>
      <option>...</option>
    </select>
  </div>
  <div class="medium:col-2">
    <label for="inputZip" class="form-label">Zip</label>
    <input type="text" class="form-input" id="inputZip">
  </div>
  <div class="col-12">
    <div class="form-check">
      <input class="check-input" type="checkbox" id="gridCheck">
      <label class="check-label" for="gridCheck">
        Check me out
      </label>
    </div>
  </div>
  <div class="col-12">
    <button type="submit" class="button primary">Sign in</button>
  </div>
</form>

Horizontal form

Create horizontal forms with the grid by adding the .row class to input groups and using .col-*-* classes to specify the width of labels and controls. Add .col-form-label to <label> elements for vertical centering with their associated form inputs.

You may need to use margin or padding utilities to achieve the desired alignment. In the example below, padding-top is removed from the radio group label to better align the text baseline.

Radios
HTML
<form>
  <div class="row mb-medium">
    <label for="inputEmail3" class="small:col-2 col-form-label">Email</label>
    <div class="small:col-10">
      <input type="email" class="form-input" id="inputEmail3">
    </div>
  </div>
  <div class="row mb-medium">
    <label for="inputPassword3" class="small:col-2 col-form-label">Password</label>
    <div class="small:col-10">
      <input type="password" autocomplete="current-password" class="form-input" id="inputPassword3">
    </div>
  </div>
  <div class="row mb-medium">
    <div class="small:col-10 small:offset-2">
      <div class="form-check">
        <input class="check-input" type="checkbox" id="gridCheck1">
        <label class="check-label" for="gridCheck1">
          Example checkbox
        </label>
      </div>
    </div>
  </div>
  <div class="row mb-medium" role="group" aria-labelledby="gridRadiosLabel">
    <div class="col-form-label small:col-2 pt-0" id="gridRadiosLabel">Radios</div>
    <div class="small:col-10 stack-container">
    <div class="vstack small:hstack gap-medium row-gap-xsmall">
      <div class="form-check">
        <input class="check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
        <label class="check-label" for="gridRadios1">
          First radio
        </label>
      </div>
      <div class="form-check">
        <input class="check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
        <label class="check-label" for="gridRadios2">
          Second radio
        </label>
      </div>
      <div class="form-check disabled">
        <input class="check-input" type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
        <label class="check-label" for="gridRadios3">
          Third disabled radio
        </label>
      </div>
    </div>
    </div>
  </div>
  <div class="row mb-medium">
    <div class="small:col-10 small:offset-2">
      <button type="submit" class="button primary">Sign in</button>
    </div>
  </div>
</form>

Horizontal label sizing

Match label sizes to corresponding input sizes using these modifier classes:

  • .col-form-label-small for aligning with small inputs (.form-input.small)
  • .col-form-label-large for aligning with large inputs (.form-input.large)

These classes maintain proper vertical alignment between labels and inputs of different sizes. They adjust the font size, line height, and padding to create a cohesive look in form layouts.

HTML
<div class="row mb-medium">
  <label for="colFormLabelSm" class="small:col-2 col-form-label small">Email</label>
  <div class="small:col-10">
    <input type="email" class="form-input small" id="colFormLabelSm" placeholder=".col-form-label.small">
  </div>
</div>
<div class="row mb-medium">
  <label for="colFormLabel" class="small:col-2 col-form-label">Email</label>
  <div class="small:col-10">
    <input type="email" class="form-input" id="colFormLabel" placeholder="col-form-label">
  </div>
</div>
<div class="row">
  <label for="colFormLabelLg" class="small:col-2 col-form-label large">Email</label>
  <div class="small:col-10">
    <input type="email" class="form-input large" id="colFormLabelLg" placeholder="col-form-label-large">
  </div>
</div>

Column sizing

The grid system supports placing any number of .cols within a .row — columns split the available width equally. To give a specific column more or less space, use a fixed column class like .small:col-7; remaining .cols split the rest equally.

HTML
<div class="row g-medium">
  <div class="small:col-7">
    <input type="text" class="form-input" placeholder="City" aria-label="City">
  </div>
  <div class="small:col">
    <input type="text" class="form-input" placeholder="State" aria-label="State">
  </div>
  <div class="small:col">
    <input type="text" class="form-input" placeholder="Zip" aria-label="Zip">
  </div>
</div>

Auto-sizing

Auto-sizing allows form elements to adapt to their content's width rather than spanning fixed columns. The .col-auto class creates columns that only take up as much space as needed. This technique is particularly useful for:

  • Forms with varying field lengths
  • Layouts where field sizes should match their expected content
  • Compact, space-efficient forms with minimal wasted space
  • Input groups with add-ons or buttons that should be optimally sized

When combined with flexbox alignment utilities like .align-items-center, auto-sizing creates clean, professional form layouts.

@
HTML
<form class="row gy-small gx-medium align-items-center">
  <div class="col-auto">
    <label class="visually-hidden" for="autoSizingInput">Name</label>
    <input type="text" class="form-input" id="autoSizingInput" placeholder="Jane Doe">
  </div>
  <div class="col-auto">
    <label class="visually-hidden" for="autoSizingInputGroup">Username</label>
    <div class="input-group">
      <div class="input-addon">@</div>
      <input type="text" class="form-input" id="autoSizingInputGroup" placeholder="Username">
    </div>
  </div>
  <div class="col-auto">
    <label class="visually-hidden" for="autoSizingSelect">Preference</label>
    <select class="form-input" id="autoSizingSelect">
      <option value="" selected>Choose...</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
  </div>
  <div class="col-auto">
    <div class="form-check">
      <input class="check-input" type="checkbox" id="autoSizingCheck">
      <label class="check-label" for="autoSizingCheck">
        Remember me
      </label>
    </div>
  </div>
  <div class="col-auto">
    <button type="submit" class="button primary">Submit</button>
  </div>
</form>

Auto-sizing can be combined with fixed-width columns for hybrid layouts:

@
HTML
<form class="row gx-medium gy-small align-items-center">
  <div class="small:col-3">
    <label class="visually-hidden" for="specificSizeInputName">Name</label>
    <input type="text" class="form-input" id="specificSizeInputName" placeholder="Jane Doe">
  </div>
  <div class="small:col-3">
    <label class="visually-hidden" for="specificSizeInputGroupUsername">Username</label>
    <div class="input-group">
      <div class="input-addon">@</div>
      <input type="text" class="form-input" id="specificSizeInputGroupUsername" placeholder="Username">
    </div>
  </div>
  <div class="small:col-3">
    <label class="visually-hidden" for="specificSizeSelect">Preference</label>
    <select class="form-input" id="specificSizeSelect">
      <option value="" selected>Choose...</option>
      <option value="1">One</option>
      <option value="2">Two</option>
      <option value="3">Three</option>
    </select>
  </div>
  <div class="col-auto">
    <div class="form-check">
      <input class="check-input" type="checkbox" id="autoSizingCheck2">
      <label class="check-label" for="autoSizingCheck2">
        Remember me
      </label>
    </div>
  </div>
  <div class="col-auto">
    <button type="submit" class="button primary">Submit</button>
  </div>
</form>

Inline forms

Create responsive horizontal form layouts with the .row-cols-* classes. These layouts adapt to different screen sizes, stacking vertically on small screens and displaying horizontally on larger screens.

Key features of inline forms:

  • Use .large:row-cols-auto for responsive horizontal layouts
  • Add gutter classes for consistent spacing
  • Apply .col-12 on mobile to stack elements
  • Use .align-items-center for vertical alignment
@
HTML
<form class="row large:row-cols-auto g-medium align-items-center">
  <div class="col-12">
    <label class="visually-hidden" for="inlineFormInputGroupUsername">Username</label>
    <div class="input-group">
      <div class="input-addon">@</div>
      <input type="text" class="form-input" id="inlineFormInputGroupUsername" placeholder="Username">
    </div>
  </div>

  <div class="col-12">
    <label class="visually-hidden" for="inlineFormSelectPref">Preference</label>
    <select class="form-input" id="inlineFormSelectPref">
      <option value="" 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 class="form-check">
      <input class="check-input" type="checkbox" id="inlineFormCheck">
      <label class="check-label" for="inlineFormCheck">
        Remember me
      </label>
    </div>
  </div>

  <div class="col-12">
    <button type="submit" class="button primary">Submit</button>
  </div>
</form>

Inline form help

For compact layouts, use inline form help by applying the .form-help class to any inline element such as <span> or <small>.

Must be 8-20 characters long.
HTML
<div class="row large:row-cols-auto large:g-medium align-items-center">
<div class="col-12">
  <label for="inlineFormHelpInput" class="col-form-label">Password</label>
</div>
<div class="col-12">
  <input type="password" autocomplete="current-password" id="inlineFormHelpInput" class="form-input" aria-describedby="inlineFormHelpText" placeholder="Password">
</div>
<div class="col-12">
  <span id="inlineFormHelpText" class="form-help large:my-auto">
    Must be 8-20 characters long.
  </span>
</div>
</div>

Accessibility

When implementing form layouts, ensure forms remain accessible:

  • Always include visible labels, or use .visually-hidden for labels that must be announced by screen readers but not shown visually
  • Maintain a logical tab order that follows the visual layout of the form
  • Use semantic HTML elements like <fieldset> and <legend> to group related form controls
  • Include appropriate ARIA attributes where needed (e.g., aria-describedby for form validation messages)
  • Test keyboard navigation flow to ensure all form controls are accessible without a mouse
  • Ensure sufficient color contrast for form elements and labels
  • For complex layouts, test with screen readers to verify the form is navigable

See the Form validation documentation for more information on creating accessible validation feedback.