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 totype="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-bottomutilities (mb-*) for vertical spacing - Applying the same spacing size throughout a single form
- Using the
mediumspacing value as a default starting point
<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-classesSass variable to be enabled (enabled by default).
Basic grid layout
Use the .row and .col classes to create evenly-spaced columns within a form:
<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.
<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:
<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.
<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-smallfor aligning with small inputs (.form-input.small).col-form-label-largefor 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.
<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.
<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.
<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:
<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-autofor responsive horizontal layouts - Add gutter classes for consistent spacing
- Apply
.col-12on mobile to stack elements - Use
.align-items-centerfor vertical alignment
<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>.
<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-hiddenfor 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-describedbyfor 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.