Skip to the page

MCSS-Lite 0.4.1

GitHub

Form field c-form-field

StableComponent · since 0.1.0

Wraps one form control with its label, help text and error message.

Pick this part

Pick c-form-field for

  • Any form control that needs a label, help text or an error message.
  • Each field of a form; stack the fields with l-stack.

Pick another part for

  • A search box in a toolbar with a visible button: a labelled c-input inside l-cluster is enough, with a visually hidden label.

Build it

  1. Start with <div> and add class="c-form-field".
  2. Add the required parts: c-form-field__label.
  3. Add the parts you need: c-form-field__help, c-form-field__error.
  4. Add data-state="error" when a group of checkboxes or radios needs attention. Set aria-describedby on the fieldset pointing at its c-form-field__error; ARIA doesn't allow aria-invalid on a fieldset or a radio.

We'll send the invite here.

Use at least 12 characters.

Show markup 22 lines
<form class="l-stack" novalidate>
  <div class="c-form-field">
    <label class="c-form-field__label" for="email">Work email</label>
    <input class="c-input" id="email" type="email" autocomplete="email" aria-describedby="email-help">
    <p class="c-form-field__help" id="email-help">We'll send the invite here.</p>
  </div>

  <div class="c-form-field">
    <label class="c-form-field__label" for="password">Password</label>
    <input class="c-input" id="password" type="password" data-state="error" aria-invalid="true" aria-describedby="password-error">
    <p class="c-form-field__error" id="password-error">Use at least 12 characters.</p>
  </div>

  <div class="c-form-field">
    <label class="c-form-field__label" for="org">Organization</label>
    <input class="c-input" id="org" type="text" value="Acme Inc." data-state="disabled" disabled>
  </div>

  <div class="l-cluster">
    <button type="submit" class="c-button c-button--primary">Create account</button>
  </div>
</form>

Check your build

Each piece that doesn't fit was run through mcss-lite validate when this page was built. The output below is real.

Fits

Link help and error text to the control with aria-describedby.

For delivery updates only.

Show markup 5 lines
<div class="c-form-field">
  <label class="c-form-field__label" for="phone">Phone number (optional)</label>
  <p class="c-form-field__help" id="phone-help">For delivery updates only.</p>
  <input class="c-input" id="phone" type="tel" autocomplete="tel" aria-describedby="phone-help">
</div>

validate: 0 issues

Doesn't fit

Don't use the elements outside their block: the help text loses its spacing and link.

<p class="c-form-field__help">For delivery updates only.</p>

validate

  • warning "c-form-field__help" should be inside an element with class "c-form-field". [element-outside-block]

Fits

Space fields with l-stack.

Show markup 10 lines
<form class="l-stack">
  <div class="c-form-field">
    <label class="c-form-field__label" for="first">First name</label>
    <input class="c-input" id="first" autocomplete="given-name">
  </div>
  <div class="c-form-field">
    <label class="c-form-field__label" for="last">Last name</label>
    <input class="c-input" id="last" autocomplete="family-name">
  </div>
</form>

validate: 0 issues

Doesn't fit

Don't push fields apart with margins on the field.

<div class="c-form-field" style="margin-bottom: 24px">
  <label class="c-form-field__label" for="first2">First name</label>
  <input class="c-input" id="first2">
</div>

validate

  • warning Components must not set their own margin. Wrap them in a layout primitive (l-stack, l-cluster…) instead. [golden-rule]

Spec sheet

Apply to <div> <fieldset>

Elements
ClassOnWhat it does
c-form-field__label required<label> <legend>The field label.
c-form-field__help<p> <div> <span>Hint shown below the control.
c-form-field__error<p> <div> <span>Error message shown when the control has data-state="error".
States
StateMeaningPair it with
data-state="error"A group of checkboxes or radios needs attention. Put it on the fieldset: the controls in it take the error keyline.Set aria-describedby on the fieldset pointing at its c-form-field__error; ARIA doesn't allow aria-invalid on a fieldset or a radio.
Tokens
TokenValue (light / dark)
--color-text-muted#343a40 / #cfdae5
--color-text-subtle#495057 / #a9bacb
--color-text-error#721c24 / #f4a9b0

Accessibility

  • Connect label and control with for/id.
  • Give help and error elements ids and list them in the control's aria-describedby.
  • Use role="alert" or a live region on the error when it appears after submit.

Wording

  1. Labels are short nouns in sentence case: "Email address", not "Please Enter Your Email".
  2. Help text explains format or why you ask; keep it to one sentence.
  3. Mark optional fields "(optional)" and ask only for what you need.
  4. After a failed submit, list every error at the top of the form, each linked to its field.

All content rules

Fits with

Researched from