The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

Form patterns

Guidelines for delivering user-centric forms comprised of Helios form components and primitives.

A form is a container housing various inputs and controls that display and collect data. These guidelines identify common patterns for designing and assembling a consistent, user-centric form.

These guidelines are meant to help and inform teams how to design and build forms. There are currently no Ember or Figma components to support these patterns.

Spacing

Spacing between sections, fields, text, and other form elements should follow a decreasing scale on an 8px grid. This creates a consistent vertical rhythm between elements and reinforces a natural hierarchy and association between elements.

Form

A form acts as a layout mechanism by wrapping the content, fields and actions to apply consistent spacing while simultaneously handling the logic for submitting information and data collected by the fields.

As a layout mechanism, a form consisting of more than one section should use a 32px gap in between sections.

Form container

Sections

A section occupies the largest hierarchy within the form. Sections organize text, fields (inputs, checkboxes, toggles, etc.), and actions into logical sets. There should be a 32px vertical gap between each section within the form container.

Example of multiple sections in a form

Fields

A field describes a form control and label pairing. When displaying multiple fields within a section, there should be a 24px gap between each field.

Example of multiple fields in a section

Sets

Fields may be organized in a set either horizontally or vertically if they are collecting related information or information that is part of the same object. Within a set there should bea 16px gap either horizontally (creating multiple columns), or vertically between each field.

Example of fields organized in a set

Don’t

Don't horizontally organize field types in a set that are related but not of the same type, e.g., a text input and a toggle.

Organizing different field types

Do

Do stack fields of different types vertically.

Organizing different field types

Common sets of fields can include:

  • Credit card information: card number, expiration data, security code
  • Multi-line address field
  • First and last name

Alignment

Fields organized in a horizontal set should be aligned to the baseline of each element to account for fields with helper text.

Baseline alignment within a set

Button sets

Organize buttons based on the Button Set guidelines, e.g., using a 16px horizontal gap between buttons. More specifications and examples can be found in the documentation for button organization.

Button set

Layout

Single-column

We recommend most forms use a single-column layout as it makes the information easier to parse and reinforces the sequential nature of filling out a form.

If a form uses a single-column layout, consider setting a maximum width on the form; this can be achieved by using a size or unit relative to the page, viewport, or container size, e.g., viewport width unit (vw), percentage width (50%), or a character unit (ch).

The web is a fluid medium. A relative width will adjust based on the viewport and container width. Designing and building a form with a maximum and minimum width will ensure a graceful expansion and contraction within the viewport.

Multi-column

Horizontal sets of form elements creates a multi-column layout within the form.

Do

Use a consistent number of columns through the form.

Consistent number of columns

Don’t

Don't organize a set of fields in two columns and another set in three columns.

Inconsistent number of columns

Don’t

Don't exceed more than three fields in a horizontal set. In most scenarios it's best to limit the number of columns in a form or section to two.

Three field maximum in a set

Do

Stack fields vertically when the width of the viewport and form container shrinks.

Stack fields

The width of the overall form can impact multi-column layouts. Use set organization logically based on the layout, width of the page, and overall UX strategy in the application.

Refer to the button organization stacking guidelines when determining how buttons should stack as the viewport condenses.

Text

In sections consisting of multiple blocks of text, use an 8px vertical gap between elements.

Example of a text section

Text elements within a form should use logical, step-based sizing to reinforce hierarchy within sections and the form itself. While specifics around type hierarchy should be determined at the application level, adhering to these guidelines will help establish consistency at the page level and when constrained within another element or component.

Order and organization

Fields within a form generally fall into three need-based categories that can determine order and organization within a form: technical and application needs, user needs, and business needs. These categories don't exist in isolation but have a cumulative effect on how a user perceives a form and how likely they are to complete it.

Need-based organization

Technical and application needs

Sometimes the values or options for a given field depend on information or selection from a previous field.

Generally, fields that are dependencies for other fields benefit from being organized closer to the start of a form. For example, selecting a cluster tier reveals options for cluster sizes that are only available for the previously selected tier.

Dependencies within forms example

User needs

Users benefit from logical organization and progressive organization, organizing fields from easiest to hardest.

This can help increase form completion by:

  • giving the user a sense of accomplishment early on through “quick wins”
  • reducing the probability of the user abandoning a form when they’ve already completed the “easier” segments.

Business needs

Organizing fields based on their importance (high to low) to completing the form can help minimize abandonment, a crucial aspect of meeting business goals and metrics.

Logical organization

Organize fields logically; consider how users fill in information based on the context.

For example, when filling out a payment form, organize the fields in the same order as they appear on a credit card or payment method: name, card number, expiration date, security code.

Visual organization

Once a logical organization has been established,

  • categorize elements and fields into sections,
  • introduce typographic elements to establish hierarchy,
  • and, if necessary, use dividers to differentiate sections clearly.

Each one of these methods will help the user better parse and understand the relationships between each section and the fields contained within.

Sizing

Length

Since longer forms can result in a lower completion rate, we recommend looking for ways to reduce the overall number of fields whenever possible.

If a field is optional, consider whether it’s actually needed in the form. If the information isn’t critical to the experience or feature, can the field be removed?

Multiple sections

Using sections based on the relationship between fields can make a longer form seem less complex. Introducing typographic elements and dividers can further aid the hierarchy of the form and differentiate sections from one another.

Using dividers

Dividers introduce more visual hierarchy and differentiation in longer, complex forms.

Use dividers to break up different types of content and categories within a form. Only use dividers between sections, not between fields.

Do

Include a 24px gap above and below to separate the divider from the surrounding form elements; otherwise, it can appear "attached" to a specific section or field.

Spacing using dividers

Don’t

Don’t use dividers at the end of the last section between the fields and the button set or actions.

Spacing using dividers

Do

Instead, use the section spacing value of 32px.

Spacing between trailing actions

Multiple steps or pages

Consider breaking the form into multiple steps or pages for exceedingly long and complex forms (e.g., creating a cluster). For multi-step forms, use a Stepper to indicate status and the user’s location within the form.

Width

The width of a form and the fields it contains are largely dependent on the context the form is in, but adhering to these high-level guidelines can make a complex form approachable and introduce consistency in the UX.

Field width

Generally, the width of a field should be wide enough to account for the estimated width of the content it accepts. This gives the user an accurate sense of the character length and type of content the field accepts and is important in setting user expectations.

Responsive properties

As the viewport shrinks, the form width should expand relative to the viewport width, eventually occupying the entire width of the viewport or page. Horizontal sets of fields that result in a multi-column layout should stack vertically as the viewport shrinks.

Required and optional

For complex forms, indicate required fields. This is the most explicit and transparent method and ensures users don't have to make assumptions.

For shorter, simpler forms, indicate optional fields instead.

Don't mix required and optional labels, stick to one or the other. Using one method can imply that fields without a label are the inverse of whatever method you choose, though expecting the user to carry this knowledge through a complex form can cause unnecessary validation errors when required fields aren't labeled.

Copying an input value

If a user needs to copy the value within an input, consider pairing a CopyButton with the input control. This can reduce the manual friction of copying a value to a single targeted action.

CopyButton paired with an input control

Visit the CopyButton guidelines for more details on this specific composition.

Anatomy

Elements and content within a form are variable but can be broken down into sections that correspond with different types of content.

Form pattern anatomy

Type Description
Form The exterior container that wraps other form elements and sections. The form (<form>) handles the logic and submission actions for the collected data.
Section Consists of multiple content types (text, fields) and groups content
Text Titles, headlines, descriptions, and supporting content that further describe the content of the form or specific sections within a form. Typically text elements are wrapped in a <legend>.
Fields An array of one or more fields which can be any input type; text input, toggle, radio, textarea, or any other Helios Form component.
Group Layout mechanism to group like elements together
Actions Responsible for submitting the form or giving the user a method to cancel, clear the form, or "go back." Refer to the button organization for more details.

Helios does not currently publish any components to assist with layout and organization within forms. Rather, this anatomy is meant to establish a common language for discussing the elements within a form.

While we provide the structure and visual consistency for validation, the messaging and functionality need to be implemented by the product teams.

Form validation ensures that fields are correctly formatted, required fields are not empty, and the data being submitted matches the requirements for application. A successful validation strategy relies on three key concepts:

  1. Uses clear language: the validation message should be human readable and easy to understand.
  2. Displayed at the right time: The validation message should be displayed as soon as possible to when the error occurred.
  3. Displayed in the right place: the validation message should be noticeable and located where the error occurred.

At this time Helios components only support error validation. If you have a need for success validation in your application please submit a request.

Types of validation

We recommend using a combination of client-side and server-side validation for the best user experience.

Client-side

Client-side validation is an initial check in the browser to ensure that required fields aren’t empty and the values are in the correct format.

Example of client side form validation

Server-side

Server-side validation provides a more thorough check on the server once the data has been submitted and helps keep our applications safe.

Example of server side form validation

Validation methods

When validation is displayed to the user impacts the time it takes to complete a form and the amount of context-switching required by the user to resolve errors.

The best user experience is often a combination of different methods depending on the type of data being collected, the length of the form, and application security protocols.

We do not recommend using HTML5 validation (for example, the required attribute). Despite being a standard its current implementation has major flaws:

  • It moves the focus to the input, but it doesn’t play back the associated label, so screen reader users become unaware of their location on the page.
  • The error message is not persistent – as soon as the user interacts with the page, it disappears. If you use the pattern attribute to define a required format, the error message is often generic (‘please match the required format’) which doesn’t help users to recover from this state.

For this reason, we recommend creating your validation mechanism using our form components, following our recommendations, and providing clear and specific error messages.

Validation on focus change

Validation on focus change occurs on the client and refers to validating a field when it loses focus via an onblur event.

This method is immediate in the sense that it displays an error directly after a field has been filled out, while not interrupting the user while they are in the process of filling out a field.

Use this method whenever possible to resolve an error while the user is still in the context of the erroring field. This can help limit the amount of context switching necessary when filling out a form and reduce the cognitive load on the user.

Validation on submit

Validating a form on submission can occur on the client or the server and can be used to display errors after interacting with the primary submit button in the form. This method can manifest in many use cases including:

  • Validating that each required field in a form is filled.
  • Validating that the input data matches the formatting expectations of the application and the server.

Delayed validation

Delayed validation occurs on the client and refers to validating the field after a lapse in keystrokes or a specific interval of time, e.g., 500ms or 0.5 seconds. Once the user has stopped input into the field or after the interval of time has expired, the field is validated without an onblur event occurring.

This method can be invasive and result in unintended validation errors by assuming the user has completed filling out a field. Thus, we recommend implementing either of the previous methods prior to delayed validation for most forms.

Consider a user entering their credit card information; they may repeatedly reference a physical card when inputting the card number, which can cause extended delays between keystrokes and result in displaying a validation error preemptively.

Displaying validation

Where validation is displayed impacts the cognitive load on the user and can make resolving errors in long forms more challenging and time consuming.

Inline validation

Display client-side validation errors within a specific field inline with the field using the built-in invalid input state and the accompanying Error contextual component.

Inline validation error

Form-level validation

Display server-side errors using a Critical Inline Alert above the form listing all errors with links to each invalid field.

Form level validation error

Validation interaction

If a validation error occurs in a field outside of the viewport, scroll the user to the error. If there are multiple fields in error, scroll the user to the first (or topmost) error in the form. Form-level validation errors should be scrolled to first and take precendence over individual fields in error. This commonly occurs in long, complex forms when a form-level error occurs.


Related