Structure to follow for consistent and accessible forms.

Whenever possible, we only use semantic HTML elements (ex: fieldset, legend) to style and lay out forms. But when required, we have a number of BEM classes to help build flexible but consistent forms.

Elements

All elements below are required unless marked as optional.

Form

Top-level element required to for all forms. In order for all the default base styles to be applied, a class "ui-icon" must be used.

Fieldset

Used to visually and semantically group multiple form inputs together.

Legend (optional)

Legend is used in conjunction with fieldset to display a title for the fieldset group

Label

Each input should have a label. By default, we recommend to wrap the <label> around the input, this allows the input to get focus when we click the label without having to use ID or for="" attributes.

An optional sublabel can be displayed between the label and text input, by adding a class "ui-form__sublabel" to an element (div).

Input

Input (or radio, checkbox, textarea, etc...) should be placed inside a label element.

Error message (optional)

Validation message ("ui-form__error") displayed when form field has error(s).

Basic

Fieldset legend

Usage

<!-- basic form -->
<form class="ui-form">

  <!-- related form inputs should be grouped under a <fieldset> -->
  <fieldset>
    <legend>...</legend>

    <!-- each form input is inside a div with class "ui-form__group" -->
    <!-- this allows better control of the layout for different breakpoints -->
    <div class="ui-form__group">
      <label>
        <div class="ui-form__label">...</div>
        <div class="ui-form__sublabel">...</div>
        <div class="ui-form__input-wrapper">
          <input class="ui-input" type="text" />
        </div>
      </label>
    </div>

    <div class="ui-form__group">
      <label>
        <div class="ui-form__label">...</div>
        <div class="ui-form__sublabel">...</div>
        <div class="ui-form__input-wrapper">
          <input class="ui-input" type="text" />
        </div>
      </label>
    </div>
  </fieldset>
</form>

Select

Fieldset legend

Usage

<!-- dropdown (select) -->
<form class="ui-form">

  <!-- related form inputs should be grouped under a <fieldset> -->
  <fieldset>
    <legend>...</legend>

    <div class="ui-form__group">
      <label>
        <div class="ui-form__label">...</div>
        <div class="ui-form__sublabel">...</div>

        <!-- dropdown component -->
        <div class="ui-form__dropdown-wrapper">

          <!-- the <select> will be hidden with CSS but its value can be updated with javascript -->
          <!-- this allows the form to be submitted with the chosen value -->
          <select>
            <option>...</option>
            <option value="1">...</option>
            <option value="2">...</option>
            <option value="3" disabled="">...</option>
          </select>

          <!-- the custom dropdown markup starts here -->

          <!-- the "ui-dropdown" element takes 2 modifier classes: -->
          <!-- "ui-dropdown--active"  ==>  expands the options list -->
          <!-- "ui-dropdown--selected"  ==>  collapses the options list and displays the selected options -->
          <div class="ui-dropdown">
            <button class="ui-dropdown__selection">
              <div class="ui-dropdown__placeholder">...</div>
              <div class="ui-dropdown__current">...</div>
            </button>

            <ul class="ui-dropdown__list">
              <li class="ui-dropdown__option">
                <button class="ui-dropdown__btn">...</button>
              </li>
              <li class="ui-dropdown__option">
                <button class="ui-dropdown__btn">...</button>
              </li>
              <li class="ui-dropdown__option ui-dropdown__option--disabled">
                <button class="ui-dropdown__btn">...</button>
              </li>
            </ul>
          </div>
        </div>
      </label>
    </div>
  </fieldset>
</form>

Errors

Fieldset legend

Usage

<!-- form with errors -->
<form class="ui-form">

  <!-- related form inputs should be grouped under a <fieldset> -->
  <fieldset>
    <legend>...</legend>

    <!-- form group has an error modifier class -->
    <div class="ui-form__group ui-form__group--error">
      <label>
        <div class="ui-form__label">...</div>
        <div class="ui-form__sublabel">...</div>
        <div class="ui-form__input-wrapper">
          <input class="ui-input" type="text" />
        </div>

        <!-- a message element is added to display error/warning messages -->
        <div class="ui-form__message">...</div>
      </label>
    </div>
  </fieldset>
</form>

2 Columns

For multi-column form layouts, simply use the grid and include .ui-form__group within each column.

Fieldset legend

Usage

<!-- 2-colum form -->
<!-- will render any number of "ui-form__group" in 2 columns -->
<form class="ui-form">
  <fieldset>
    <legend>...</legend>

    <!-- use grid row/col to layout form inputs in columns -->
    <div class="ui-row">
      <div class="ui-col">
        <div class="ui-form__group">...</div>
      </div>
      <div class="ui-col">
        <div class="ui-form__group">...</div>
      </div>
    </div>
  </fieldset>
</form>