#ClimateEmergency

Form

Open in Storybook Open in Figma

This page describes how to assemble individual inputs and labels into forms.

Rules For Accessibility
  • For complex forms add instructions on top of the form to help users understand how to correctly complete the form.
  • Provide instructions to help users understand how to complete individual form controls (like in which format dates should be typed in).
  • Validate the user input and provide options to undo changes and confirm data entry.
  • Divide long forms into multiple smaller forms that constitute a series of logical steps or stages and inform users about their progress.

Grid

Form input fields and their labels need to be placed in grids so they behave properly in all tiers.

  • Use .row without a .container around it to avoid the form to be indented left and right.
  • Use .row.form-group and in it two columns (label, input).
  • The first column is either an actual <label> or a fake one, depending on whether labelling the element in the second column is allowed. It must have the .col-form-label class and a .col-* sizing class.
  • The second column is a <div> that contains the actual input(s). It too needs .col-* classes as usual.
Rules For Accessibility
  • Each input field needs a label. Use a <label> tag with the ‘for’ attribute to correctly assign the label to the input. This label is not necessarily the one displayed in the first column, as e.g. a checkbox may have its label appended.
  • If we display read-only text instead of an input field, we must use a fake label, i.e. no <label> element, as there would not be an <input> element to associate it with.
  • Group and associate related form controls with <fieldset> and <legend>.

Single-column

In George, forms are usually single column where there is each input field (and its label) in each line. This kind of form uses ‘To-the-left’ Labels (see below).

Loading demo…

Two-column

In some rare cases (e.g. the address book), there are two columns per line. In this case, you need to set a grid to make all input fields properly rearrange on small devices. This kind of form uses ‘Above’ Labels (see below) and requires the use of a .row.g-form-multicol row containing two .col-*-6 columns, which then contain the individual .row.form-groups. In these form groups, both the label and the input fields are set in using .col-12. This nested grid is necessary to make all spacings uniform across all tiers and other kinds of forms in other cards on the same page.

Loading demo…

Labels

‘To-the-left’ labels

In this default type of labels in forms of all kind in George.

Loading demo…
Rules For Designers
  • Labels are left-aligned and presented in semi-bold 600.
  • Labels and their input field are placed using a 4-8 grid.
  • Input fields fill 100% width of their cell.
  • On XS/SM tier, ‘To-the-left’ labels automatically turn into ‘Above’ labels.

‘Above’ labels

In this case, the label is above the input field. They are only used in two-column layouts or when ‘To-the-left’ are shown on smaller tiers:

Loading demo…
Rules For Designers
  • Labels are left-aligned with the border of the input field below.
  • Input fields fill 100% width of their cell.
  • Vertical spacing between label and input field is 10px.
  • Vertical spacing between the input field and the following label 25px.

Spacing

There are two kinds of horizontal spacings when using forms.

The default larger spacings are fine when mixing text lines with larger input fields.

Loading demo…

When no input fields are used, the default spacings might be too large. They can be avoided by adding the .g-form-compact class to each row. However, those tighter spaces are incompatible with input fields and can only be used in summary pages that feature only text:

Loading demo…
Rules For Designers
  • There is a 40px spacing between regular rows (label-to-label). This results in a 16px spacing between input fields.
  • There is a 20px spacing between compact rows (label-to-label).
  • Too long label texts are ellipsed (…).
  • Only labels and amounts are semi-bold 600.

FormField

Every Form has one or many FormFields. At the very least, a FormField comes with a label and an input. The input determines what the user should enter/select, and at the same time is the primary driver for the FormField’s overall look. Many props exist that change the appearance further, most notably variant, labelColumnWidth, and labelPosition (in charge of the already covered label placement). And then there are boolean props like required, disabled, and invalid.

Loading demo…

It does not stop there, many more things can be configured, which when present will orbit around label and input: A description, small alerts, an interactive addOn, and more.

Description

This section handles optional small text below an input field that may contain help or additional information about that field:

Loading demo…
Rules For Accessibility
  • While it is tempting to think the caption is attached to the input field by providing a reference (either with the aria-labelledby or the aria-describedby attribute), in this case aria-details is used, because the content of the caption may get quite long, and rich content may be used.
  • Due to the use of aria-details, the caption has no impact on the accessible description, so it is not announced by assistive technology while the focus is on the input field. Hence the caption should not contain information that is required to know while the user is typing.

Alerts

Error messages for individual input fields (as opposed to the overall form) should be placed directly following the input field using small Alerts.

Loading demo…
Rules For Accessibility
  • Notify users about successful form completion as well as input errors.
  • Use the ARIA role ‘alert’ to notify the user without them having to focus the element holding the message.
  • Provide instructions to help the user correct mistakes.
  • Assign the instructions to the input that caused the error by adding aria-describedby="id-of-error-container" to the input field.

Large variant REACT-ONLY

In the large variant of a FormField, there is a larger input box and the label can be positioned above, aside or inside it.

Loading demo…
Rules For Designers
  • The padding in a large FormField is 16px.
  • The input in a large FormField is bold and it has a font-size of 40px.
  • When placed inside the input, the label is semi-bold 600 and it has a font-size of 14px.

Just like regular FormFields, lthe large variant can also have a description (rich text), specified via the description prop. However, unlike regular FormFields, the description is no longer placed underneath, but is now displayed as a small section inside the input.

Loading demo…

Add-on REACT-ONLY

An interactive add-on can be added to a FormField, usually a Button or a Link. The visual placement of the add-on on screen is highly responsive and determined by the overall configuration of the FormField.

HINT Do not confuse FormField add-ons with InputGroup add-ons. A FormField can have an add-on, and its input can be an InputGroup that itself has add-ons. The former is always visually separated from FormField’s label and input.

Loading demo…
Rules For Developers
  • When the add-on is a Button, make it VARIANT.TERTIARY, SIZE.SMALL, and FULL_WIDTH.NEVER.
  • When the FormField is disabled, the add-on is not affected, as there may be cases when the add-on provides useful information related to the disabled control, e.g. it opens a Modal. So whenever the add-on should be disabled too, it has to be done manually.
  • There are two scenarios where the add-on won’t be rendered:
    1. in any FormField with LABEL_POSITION.INSIDE, and
    2. in a large FormField with LABEL_POSITION.ASIDE.

Buttons

To properly group Buttons, a ButtonGroup with the modifier .g-group-button-form should be used. This automatically sets the right margins and pulls the primary button to the first position on small devices.

Loading demo…
Rules For Developers
  • Buttons should be SIZE.REGULAR
  • Place the VARIANT.PRIMARY Button at the end of the ButtonGroup