Forms

HTML forms are made up of many elements, including Form, Fieldset, Legend, Label, Input, Select/Option, Textarea, and Button.

Under the new styleguide rules:

  • .form-basic - Class to define new standard form and to avoid blow outs with legacy CSS.
  • inputs should never share a line within a form, but should always be stacked.
  • inputs should be wrapped within the label element to both aid in accessibility and to facilitate default display overrides in the cases of radio and checkbox elements.

    Note: pseudo-element rules that target different browsers break when grouped together and must be written separately.

Form Inputs

The "text" type is the most basic form input, but plenty of other types exist. HTML5 added to the pool by introducing a number of new input types to handle various alphanumeric and time-based input formats.

helper text
<label for="this-field" class="input-text has-feedback">
  <span class="field-name">Input Label <abbr title="required">- required</abbr></span>
  <input type="text" name="this-field" id="this-field" />
</label>
<span class="field-help">helper text</span><br>

Textarea Element

Can be used for long-form text like comments, notes, and instructions.

<form action="" class="form-basic">

<label for="this-textarea" class="input-text">
  <span class="field-name">Textarea Label</span>
  <textarea name="this-textarea" id="this-textarea"></textarea>
</label>

</form>

Alphanumeric Input Types

Use the input type value to build forms semantically, and influence the layout of the soft keyboard on a mobile device.

<form action="" class="form-basic">

<label for="input-email" class="input-text">
  <span class="field-name">Email Input Label</span>
  <input type="email" name="input-email" id="input-email" autocapitalize="none" />  
</label>

<label for="input-number" class="input-text">
  <span class="field-name">Number Input Label</span>
  <input type="number" name="input-number" id="input-number" />  
</label>

<label for="input-password" class="input-text">
  <span class="field-name">Password Input Label</span>
  <input type="password" name="input-password" id="input-password" autocapitalize="none" />
</label>

<label for="input-search" class="input-text">
  <span class="field-name">Search Input Label</span>
  <input type="search" name="input-search" id="input-search" />
</label>

<label for="input-tel" class="input-text">
  <span class="field-name">Tel Input Label</span>
  <input type="tel" name="input-tel" id="input-tel" />
</label>

<label for="input-url" class="input-text">
  <span class="field-name">URL Input Label</span>
  <input type="url" name="input-url" id="input-url" />
</label>

</form>

Time-based Input Types

These inputs are handy for forms that require scheduling.

<form action="" class="form-basic">

<label for="input-date" class="input-text">
  <span class="field-name">Date Input Label</span>
  <input type="date" name="input-date" id="input-date" />
</label>

<label for="input-datetime-local" class="input-text">
  <span class="field-name">Datetime-Local Input Label</span>
  <input type="datetime-local" name="input-datetime-local" id="input-datetime-local" />
</label>

<label for="input-month" class="input-text">
  <span class="field-name">Month Input Label</span>
  <input type="month" name="input-month" id="input-month" />
</label>

<label for="input-time" class="input-text">
  <span class="field-name">Time Input Label</span>
  <input type="time" name="input-time" id="input-time" />
</label>

<label for="input-week" class="input-text">
  <span class="field-name">Week Input Label</span>
  <input type="week" name="input-week" id="input-week" />
</label>

</form>

Button-style Input Types

HTML offers a number of ways to code buttons, including as an input with a type attribute. Acceptable values are "button", "reset", and "submit".

<form action="" class="form-basic">

<fieldset class="has-buttons-vertical">
  <input type="button" class="button button-tertiary" name="input-button" id="input-button" value="Button Input" />
  <input type="reset" class="button button-secondary" name="input-reset" id="input-reset" />
  <input type="submit" class="button button-primary" name="input-submit" id="input-submit" />
</fieldset>

</form>

Other Input Types

These inputs are not well-known, but can be very useful.

<form action="" class="form-basic">

<label for="input-color" class="input-text">
  <span class="field-name">Color Input Label</span>
  <input type="color" defaultvalue="#808080" value="#ff0000" name="input-color" id="input-color" />
</label>

<label for="input-file" class="input-text">
  <span class="field-name">File Input Label</span>
  <input type="file" name="input-file" id="input-file" value="File Input" />
</label>

<label for="input-range" class="input-text">
  <span class="field-name">Range Input Label</span>
  <input type="range" name="input-range" id="input-range" />
</label>

</form>

Form Toggles

The radio and checkbox browser override styles use a stand-in element to replace the default browser elements.

The radio and checkbox input needs to be positioned out of sight so that focus behavior will still be triggered and so options can still be selected via keyboard navigation.

Also, make sure tabindex="0" is placed on the field-name span. This allows it to receive focus when someone is navigating the page via their keyboard.

All radio and checkbox inputs need to be grouped in fieldsets.

Checkboxes

Can be used to toggle one or many options on or off.

Should be nested according to these rules:

  • Single checkbox, no FIELDSET
  • Group of checkboxes, wrap with a FIELDSET
Fieldset Legend
<form action="" class="form-basic">

<!-- Single checkbox, no FIELDSET -->
<label class="input-checkbox" for="checkbox" aria-checked="true" role="checkbox" >
    <input type="checkbox" id="checkbox" name="checkbox" value="checkbox value 3" />
    <button class="standin" role="presentation"></button>
    <span class="field-name" tabindex="0">Checkbox Label</span>
</label>

<!-- Group of checkboxes, wrap with a FIELDSET -->
<fieldset>

  <legend>Fieldset Legend</legend>

  <label class="input-checkbox" for="checkbox-1" aria-checked="true" role="checkbox" >
    <input type="checkbox" id="checkbox-1" name="checkbox-1" value="checkbox value 1" />
    <button class="standin" role="presentation"></button>
    <span class="field-name" tabindex="0">Checkbox Label 1</span>
  </label>

  <label class="input-checkbox" for="checkbox-2" aria-checked="true" role="checkbox" >
    <input type="checkbox" id="checkbox-2" name="checkbox-2" value="checkbox value 2" />
    <button class="standin" role="presentation"></button>
    <span class="field-name" tabindex="0">Checkbox Label 2</span>
  </label>

  <label class="input-checkbox" for="checkbox-3" aria-checked="true" role="checkbox" >
    <input type="checkbox" id="checkbox-3" name="checkbox-3" value="checkbox value 2" />
    <button class="standin" role="presentation"></button>
    <span class="field-name" tabindex="0">Checkbox Label 2</span>
  </label>

</fieldset>

</form>

Radio Buttons

Can be used to make a choice between many options.

Please note: If you're going to have inline fields, your tab index values become very important. It seems simply setting tabindex="0" doesn't behave as expected in this scenerio.

Radio Button Fieldset Legend
<form action="" class="form-basic">

<!-- Radio buttons should always be used within a FIELDSET: -->
<fieldset>

  <legend>Radio Button Fieldset Legend</legend>

  <label role="radio" aria-checked="true" for="radio-1" class="input-radio">
    <input type="radio" name="radio" id="radio-1" value="radio value 1" />
    <button role="presentation" class="standin"></button>
    <span class="field-name" tabindex="0">Radio Button Label 1</span>
  </label>

  <label role="radio" aria-checked="true" for="radio-2" class="input-radio">
    <input type="radio" name="radio" id="radio-2" value="radio value 2" />
    <button role="presentation" class="standin"></button>
    <span class="field-name" tabindex="0">Radio Button Label 2</span>
  </label>

  <fieldset class="has-inline-fields">
    <label role="radio" aria-checked="true" for="radio-3" class="input-radio has-text-input">
      <input type="radio" name="radio" id="radio-3" value="radio value 3" />
      <button role="presentation" class="standin"></button>
      <span class="field-name" tabindex="0">Radio Button Label 3 - inline text input:</span>
    </label>
    <label class="input-text" for="inline-text">
      $ <input tabindex="4" class="input-text narrow" id="inline-text" type="text" value="" />
    </label>
  </fieldset>

  <fieldset class="has-inline-fields">
    <label role="radio" aria-checked="true" for="radio-4" class="input-radio has-text-input">
      <input type="radio" name="radio" id="radio-4" value="radio value 4" />
      <button role="presentation" class="standin"></button>
      <span class="field-name" tabindex="0">Radio Button Label 4 - inline select menu:</span>
    </label>
    <label>
      <div class="select-menu" name="example">
        <select tabindex="6">
          <option>Option 1</option>
          <option>Option 2</option>
        </select>
      </div>
    </label>
  </fieldset>

</fieldset>

</form>

Unique Form Elements

Select Element

The select element is wrapped in a parent element with the class .select-menu in order to override browser default styling. This parent element doesn't have have to be a label, but it's recommended.

<form action="" class="form-basic">

<label for="example">
  <span class="field-name">Select Label</span>
  <div  class="select-menu">
    <select id="example" name="example">
      <option value="Chrome">Chrome</option>
      <option value="Firefox">Firefox</option>
      <option value="Internet Explorer">Internet Explorer</option>
      <option value="Opera">Opera</option>
      <option value="Safari">Safari</option>
      <option value="Microsoft Edge">Microsoft Edge</option>
    </select>
  </div>
</label>

</form>

Datalist Element

EXPERIMENTAL: The datalist element is intended to be used in conjunction with a text input. It offers a list of options that a user can choose from to fill the adjacent input.

<form action="" class="form-basic">

<label for="input-datalist" class="input-text html5">
  <span class="field-name">Datalist Label</span>
  <input type="text" list="input-datalist" name="input-datalist" />
  <datalist id="input-datalist">
    <option value="Chrome">
    <option value="Firefox">
    <option value="Internet Explorer">
    <option value="Opera">
    <option value="Safari">
    <option value="Microsoft Edge">
  </datalist>
</label>

</form>

Meter Element

EXPERIMENTAL: This element is intended as a quantitative data indicator, but is not approved for use by the Patterns Team.

<form action="" class="form-basic">

<label for="input-meter" class="input-text">
  <span class="field-name">Meter Label</span>
  <meter name="input-meter" id="input-meter" value="57" min="0" max="100" low="33" high="67" optimum="50"></meter>
</label>

</form>

Progress Element

EXPERIMENTAL: This element is intended as a progress indicator, but is not approved for use by the Patterns Team.

<form action="" class="form-basic">

<label for="input-progress" class="input-text">
  <span class="field-name">Progress Label</span>
  <progress name="input-progress" id="input-progress" value="57" min="0" max="100"></progress>
</label>

</form>