Docs
Use HTML forms to capture information from users.

Forms are built using two main building blocks: a form tag with a layout helper class (stacked, inline, horizontal, etc.) and a div tag with the .joy-form-element class for each form field.

<form class="joy-form--stacked">
  <div class="joy-form-element">
    ...
  </div>
</form>

Every form fields requires a text <label> element with a for="" attribute that matches the id of the corresponding form field.

<div class="joy-form-element">
  <label class="joy-form-element__label" for="username">Username</label>
  <div class="joy-form-element__control">
    <input id="username" class="joy-input" type="text"/>
  </div>
</div>

Inputs

Base

Style input elements with the .joy-input class.

The input element has support for all HTML5 types:

  • text
  • password
  • datetime
  • datetime-local
  • date
  • month
  • time
  • week
  • number
  • email
  • url
  • search
  • tel
  • color
<div class="joy-form-element">
  <label class="joy-form-element__label" for="sample1">Text Input</label>
  <div class="joy-form-element__control">
    <input id="sample1" class="joy-input" type="text" placeholder="Placeholder Text" />
  </div>
</div>

Disabled

Add a disabled="" attribute to disable any input field.

<div class="joy-form-element joy-m-bottom--small">
  <label class="joy-form-element__label" for="sample1">Disabled Input</label>
  <div class="joy-form-element__control">
    <input id="sample1" class="joy-input" type="text" placeholder="Placeholder Text" disabled=""/>
  </div>
</div>

Textarea

Style textarea elements with the .joy-textarea class.

<div class="joy-form-element">
  <label class="joy-form-element__label" for="sample2">Textarea Label</label>
  <div class="joy-form-element__control">
    <textarea id="sample2" class="joy-textarea" placeholder="Placeholder Text"></textarea>
  </div>
</div>

Radio

Radio buttons use a very specific markup structure in order to ensure they are styled the same across different browsers.

A group of radio buttons should be within a single <div class="joy-form-element">. This element should contain a div with the .joy-form-element__label for the label of the group and a .joy-form-element__control container for the group of buttons themselves.

Be sure you use the same name attribute on each of the radio inputs in a given group.

Options
<div class="joy-form-element">
  <div class="joy-form-element__label joy-form-element__label--top">Options</div>
  <div class="joy-form-element__control">
    <label class="joy-radio" for="radio-one">
      <input type="radio" name="options" id="radio-one" />
      <span class="joy-radio--faux"></span>
      <span class="joy-form-element__label">Anthem</span>
    </label>
    <label class="joy-radio" for="radio-two">
      <input type="radio" name="options" id="radio-two" />
      <span class="joy-radio--faux"></span>
      <span class="joy-form-element__label">A Way Out</span>
    </label>
    <label class="joy-radio" for="radio-three">
      <input type="radio" name="options" id="radio-three" disabled="" />
      <span class="joy-radio--faux"></span>
      <span class="joy-form-element__label">Star Wars Battlefront 2</span>
    </label>
  </div>
</div>

Checkbox

Checkboxes use a very specific markup structure in order to ensure they are styled the same across different browsers.

A group of checkboxes should be within a single <div class="joy-form-element">. This element should contain a div with the .joy-form-element__label for the label of the group and a .joy-form-element__control container for the group of buttons themselves.

Be sure you use the same name attribute on each of the checkbox inputs in a given group.

Options
<div class="joy-form-element">
  <div class="joy-form-element__label joy-form-element__label--top">Options</div>
  <div class="joy-form-element__control">
    <label class="joy-checkbox" for="checkbox-one">
      <input name="checkbox" type="checkbox" id="checkbox-one" />
      <span class="joy-checkbox--faux"></span>
      <span class="joy-form-element__label">Anthem</span>
    </label>
  </div>
  <div class="joy-form-element__control">
    <label class="joy-checkbox" for="checkbox-fifa">
      <input name="checkbox" type="checkbox" id="checkbox-fifa" />
      <span class="joy-checkbox--faux"></span>
      <span class="joy-form-element__label">A Way Out</span>
    </label>
  </div>
  <div class="joy-form-element__control">
    <label class="joy-checkbox" for="checkbox-mirror">
      <input name="checkbox" type="checkbox" id="checkbox-mirror" disabled="" />
      <span class="joy-checkbox--faux"></span>
      <span class="joy-form-element__label">Star Wars Battlefront 2</span>
    </label>
  </div>
</div>

Select

The <select> element allows the user to make a selection from a set of options. Each option is an <option> tag. Group options by wrapping them in <optgroup> elements.

<div class="joy-form-element">
  <label class="joy-form-element__label" for="selectGame">Select a Game</label>
  <div class="joy-form-element__control">
    <select id="selectGame" class="joy-select">
      <option>Anthem</option>
      <option>A Way Out</option>
      <option>Star Wars Battlefront 2</option>
      <optgroup>
        <option>Mass Effect: Andromeda</option>
        <option>Battlefield 1</option>
      </optgroup>
    </select>
  </div>
</div>

Form Layout

Several layout helpers are available to create different form layouts.

Stacked Form

A standard form layout with each .joy-form-element stacked vertically. Stacked forms will grow horizontally to fill the full width of their container.

Options
<form class="joy-form--stacked">
  <div class="joy-form-element">
    <label class="joy-form-element__label" for="stacked-text-input">Text Input</label>
    <div class="joy-form-element__control">
      <input id="stacked-text-input" class="joy-input" type="text" placeholder="Placeholder Text" />
    </div>
  </div>
  <div class="joy-form-element">
    <div class="joy-form-element__label">Options</div>
    <div class="joy-form-element__control">
      <label class="joy-radio" for="stacked-radio-one">
        <input type="radio" name="options" id="stacked-radio-one" />
        <span class="joy-radio--faux"></span>
        <span class="joy-form-element__label">Anthem</span>
      </label>
      <label class="joy-radio" for="stacked-radio-two">
        <input type="radio" name="options" id="stacked-radio-two" />
        <span class="joy-radio--faux"></span>
        <span class="joy-form-element__label">FIFA 16</span>
      </label>
    </div>
  </div>
  <div class="joy-form-element">
    <button class="joy-button" type="button">Send</button>
  </div>
</form>

Horizontal Form

Horizontal forms have a responsive layout where the .joy-form-element__label is positioned to the left of its field. The form will take a stacked layout at smaller device widths.

Options
<form class="joy-form--horizontal">
  <div class="joy-form-element">
    <label class="joy-form-element__label" for="horiz-text-input">Text Input</label>
    <div class="joy-form-element__control">
      <input id="horiz-text-input" class="joy-input" type="text" placeholder="Placeholder Text" />
    </div>
  </div>
  <div class="joy-form-element">
    <div class="joy-form-element__label">Options</div>
    <div class="joy-form-element__control">
      <label class="joy-radio" for="horiz-radio-one">
        <input type="radio" name="options" id="horiz-radio-one" />
        <span class="joy-radio--faux"></span>
        <span class="joy-form-element__label">Anthem</span>
      </label>
      <label class="joy-radio" for="horiz-radio-two">
        <input type="radio" name="options" id="horiz-radio-two" />
        <span class="joy-radio--faux"></span>
        <span class="joy-form-element__label">FIFA 16</span>
      </label>
    </div>
  </div>
  <div class="joy-form-element">
    <div class="joy-form-element__control">
      <input class="joy-button" type="submit" value="Submit" />
    </div>
  </div>
</form>

Inline Form

Inline forms layout your .joy-form-element containers in a horizontal row. This layout is responsive. At smaller widths, the labels will stack on top of the fields. At very small width, the whole form will take a stacked layout.

The inline layout works best on short forms with a small number of fields.

<form class="joy-form--inline">
  <div class="joy-form-element">
    <label class="joy-form-element__label" for="name">Name</label>
    <div class="joy-form-element__control">
      <input id="name" class="joy-input" type="text" placeholder="Luke Skywalker" />
    </div>
  </div>
  <div class="joy-form-element">
    <label class="joy-form-element__label" for="email">Email</label>
    <div class="joy-form-element__control">
      <input id="email" class="joy-input" type="text" placeholder="lskywalker@ea.com" />
    </div>
  </div>
  <div class="joy-form-element">
    <button class="joy-button" type="button">Send</button>
  </div>
</form>

Compound Form

Compound forms are used when you need to group fields together within a form. Use the fieldset and legend elements to contain and label a group of elements.

An .joy-form-element__group can contain as many element rows as you need.

Location
Address
<fieldset class="joy-form--compound">
  <legend class="joy-form-element__label">Location</legend>
  <div class="joy-form-element__group">
    <div class="joy-form-element__row">
      <label class="joy-form-element__control joy-size--1-of-2">
        <small class="joy-form-element__helper">Latitude</small>
        <input class="joy-input" type="text" />
      </label>
      <label class="joy-form-element__control joy-size--1-of-2">
        <small class="joy-form-element__helper">Longitude</small>
        <input class="joy-input" type="text" />
      </label>
    </div>
  </div>
</fieldset>
<fieldset class="joy-form--compound">
  <legend class="joy-form-element__label">Address</legend>
  <div class="joy-form-element__group">
    <div class="joy-form-element__row">
      <label class="joy-form-element__control joy-size--1-of-1">
        <small class="joy-form-element__helper">Street</small>
        <input class="joy-input" type="text" />
      </label>
    </div>
    <div class="joy-form-element__row">
      <label class="joy-form-element__control joy-size--1-of-2">
        <small class="joy-form-element__helper">City</small>
        <input class="joy-input" type="text" />
      </label>
      <label class="joy-form-element__control joy-size--1-of-2">
        <small class="joy-form-element__helper">State</small>
        <input class="joy-input" type="text" />
      </label>
    </div>
    <div class="joy-form-element__row">
      <label class="joy-form-element__control joy-size--1-of-2">
        <small class="joy-form-element__helper">ZIP Code</small>
        <input class="joy-input" type="text" />
      </label>
    </div>
  </div>
</fieldset>
<div class="joy-form-element">
  <button class="joy-button" type="button">Send</button>
</div>

For compound form inputs, the .joy-is-required class can be applied to either the .joy-form--compound element or the .joy-form-element__control elements. See example.


Read-Only State

The read-only state is used for form elements that can't be modified. For example if the a username is not editable, display it as a read-only element.

<div class="joy-form-element">
  <span class="joy-form-element__label">Username</span>
  <div class="joy-form-element__control">
    <span class="joy-form-element__static">lskywalker@ea.com</span>
  </div>
</div>

Validation State

Use error states to inform the user when a form field is invalid. Add the .joy-has-error class to the <div class="joy-form-element">. Any error message should be placed in a <span class="joy-form-element__help">.

If a form field is required, add the .joy-is-required class to the <div class="joy-form-element">.

This field is required
Help text goes here.
<form class="joy-form--stacked">
  <div class="joy-form-element joy-has-error joy-is-required">
    <label class="joy-form-element__label" for="validation-input-states">Input Error</label>
    <div class="joy-form-element__control">
      <input id="validation-input-states" class="joy-input" type="email" aria-describedby="errorSample1" required="" />
      <span class="joy-form-element__help">This field is required</span>
    </div>
  </div>
  <div class="joy-form-element joy-is-required">
    <label class="joy-form-element__label" for="validation-req-input">Required Text Input</label>
    <div class="joy-form-element__control">
      <input id="validation-req-input" class="joy-input" type="email" aria-describedby="validation-req-input" required="" />
    </div>
    <span class="joy-form-element__help">Help text goes here.</span>
  </div>
  <div class="joy-form-element joy-is-required">
    <label class="joy-checkbox" for="validation-req-radio">
      <input name="checkbox" type="checkbox" id="validation-req-radio" />
      <span class="joy-checkbox--faux"></span>
      <span class="joy-form-element__label">Required Checkbox</span>
    </label>
  </div>
  <div class="joy-form-element joy-has-error">
    <label class="joy-checkbox" for="validation-checkbox-error">
      <input name="checkbox" type="checkbox" id="validation-checkbox-error" />
      <span class="joy-checkbox--faux"></span>
      <span class="joy-form-element__label">Checkbox Error</span>
    </label>
  </div>
  <div class="joy-form-element joy-has-error">
    <label class="joy-radio" for="validation-radio-error">
      <input type="radio" name="radio" id="validation-radio-error" />
      <span class="joy-radio--faux"></span>
      <span class="joy-form-element__label">Radio Error</span>
    </label>
  </div>
</form>