Designing forms

A guide to best practice form design.

Why good form design is important

Well designed forms can make it easier to complete them which can:

  • save user’s time
  • reduce the need for support
  • increase completion rates
  • minimise user frustration
  • reduce input errors

Glossary

Label

A label is the text that describes an individual input. This could be a textarea or a single radio button in a form group.

Legend

A legend is the text that appears above a group of inputs that all belong to the same question. This could be a group of checkboxes or several text inputs that are used to capture an address. Its main purpose is to provide context or clarification for what the user is being asked to do.

Fieldset

A fieldset is used to group multiple inputs of the same type together. For example, if you use radio buttons to present a list of options related to the same question, you must group these inside a fieldset. You then use a legend to describe the group of inputs.

Form group

A form group is a wrapper that contains all the elements of a form related to a single question.

Form groups can contain:

  • a single input or multiple inputs and their associated labels
  • any hint text
  • any error messages

Layout and hierarchy

Use a single column

You must lay out forms using a single column. This allows users to focus on one question at a time with less distractions.

Forms that use multiple columns force users to scan the whole page to understand the content. It also creates issues if users use a screen magnifier to zoom into the page as they might miss parts of the form.

Placing all the form elements in a single column also means it is likely to work across all breakpoints.

Vertical spacing

The top of all form elements have a margin of spacing unit 6 ($p-su-6). This margin will appear when you use more than one form group. It allows form groups to have enough space around them to make forms easy to scan.

Question 2
<div class="p-form__form-group">
  <label class="p-form__label" for="vertical-input">Question 1</label>
  <input
    type="text"
    name="vertical-input"
    id="vertical-input"
    class="p-form__input"
  />
</div>
<div class="p-form__form-group">
  <fieldset class="p-form__fieldset">
    <legend class="p-form__fieldset-legend">Question 2</legend>
    <div class="p-form__checkbox-group">
      <div class="p-form__checkbox-item">
        <input
          type="checkbox"
          name="vertical-option-1"
          id="vertical-option-1"
        />
        <label for="vertical-option-1" class="p-form__checkbox-item-label">
          Option 1
        </label>
      </div>
      <div class="p-form__checkbox-item">
        <input
          type="checkbox"
          name="vertical-option-2"
          id="vertical-option-2"
        />
        <label for="vertical-option-2" class="p-form__checkbox-item-label">
          Option 2
        </label>
      </div>
    </div>
  </fieldset>
</div>

Altering the vertical spacing

You can increase the space between form groups to better meet your users' needs. If you do increase the spacing it’s important to do this consistently across the whole form.

However, you must not decrease the spacing as form groups would end up too close together. This can make it difficult for users to read the form or select inputs, especially for those with motor challenges.

Buttons

Placement

You must left align action buttons (for example, to submit the form or continue with it) with the edge of the input(s).

Do not place buttons to the right of the form. Users can miss them, especially if they are using a screen magnifier to zoom into the page.

<div class="p-form__form-group">
  <label class="p-form__label" for="input-name">Name</label>
  <input type="text" name="input-name" id="input-name" class="p-form__input" />
</div>
<div class="p-form__buttons">
  <button class="btn btn-primary">Continue</button>
</div>

Types

Each form must only contain one primary button. You must use it for the most important action on your form.

If you need to include any other actions use the secondary button.

<div class="p-form__form-group">
  <label class="p-form__label" for="input-detail">Provide more detail</label>
  <input
    type="text"
    name="input-detail"
    id="input-detail"
    class="p-form__input"
  />
</div>
<div class="p-form__buttons p-button-group">
  <button class="btn btn-primary">Save and continue</button>
  <button class="btn btn-secondary">Save as draft</button>
</div>

How to write button text

Button text should be short. When a button requires an action, use words like ‘save’, ‘remove’ or ‘create’, in the call to action. These words describe what action your user will be making instead of vague terms like ‘OK’.

An option to dismiss or cancel lets users feel reassured that they can opt out.

Do not disable buttons

Disabled buttons do not tell a user why they cannot take an action and are not announced by screen readers. Instead, allow users access to all actions, even if that means the user fails and must take an action to fix the problem.

For example, it’s better to let a user attempt to submit an incomplete form and then tell them what the problem is. Disabling the ‘submit’ would mean the user is forced to try and work out why they cannot submit the form themselves.

Setting legends as headings

Depending on the structure of your page it may be necessary to set a legend as heading.

<fieldset class="p-form__fieldset">
  <legend class="p-form__fieldset-legend">
    <h2>Legend</h2>
  </legend>
  <div class="p-form__form-group">
    <label class="p-form__label" for="legend-heading-input">Label</label>
    <input
      type="text"
      name="legend-heading-input"
      id="legend-heading-input"
      class="p-form__input"
    />
  </div>
</fieldset>

Capitalisation

Avoid the use of block capitals as it makes text difficult to read and is not accessible. Use capitals at the beginning of a label or heading and for names.

One thing per page vs several things per page

One thing per page is the approach popularised by GOV.UK. Forms are broken down into separate pages to ask each question. The advantages of this approach are:

  • low confidence users find them easier to use
  • they work well on mobile devices
  • they are better at handling things like errors, branches, loops and saving progress

This is a good approach to take if you are designing a form that is public facing or used infrequently.

However, if you are designing a form that will be regularly used by the same users it may make sense to have more things per page. This will reduce fatigue from repeatedly clicking ‘continue’.

If you do put more than one thing per page, then it’s important not to let the page get too long. Otherwise, it may mean users are more likely to miss bits. To avoid this, you could:

  • break the form up over multiple pages but include more than one thing per page
  • use progressive disclosure to gradually reveal additional fields which only appear when relevant

If you use progressive disclosure, you must ensure that any change in status is also relayed or announced for those using screen readers.

Structure

Set expectations early

If a user will need something to complete the form (for example, documents or relevant dates) let them know before they start entering any information. This will reduce frustration and confusion as users will not need to stop part way through completing a form to find information.

Make any eligibility requirements (for example, completion of probation period) clear early on too. This will stop users from starting the form if they are not going to be able to complete it.

Group related information

Consider what information you are asking for and group related questions together. For example, employment history.

Ask things in a logical order

Reduce the cognitive effort needed to complete the form by asking things in a logical order. For example, when asking for personal details start with ‘name’ because this is the most common thing asked about a person.

Asking questions

Required and optional questions

By default, questions should be mandatory as you should only ask for information that you need. As such, you should not need to highlight required fields. Instead, highlight any fields that are optional by including ‘(optional)’ at the end of the label or legend text.

Do not highlight required fields with an asterisk as it can be distracting or confusing to users.

Legend
<fieldset class="p-form__fieldset">
  <legend class="p-form__fieldset-legend">Legend</legend>
  <div class="p-form__form-group">
    <label class="p-form__label" for="input-required">Label</label>
    <input
      type="text"
      name="input-required"
      id="input-required"
      class="p-form__input"
    />
  </div>
  <div class="p-form__form-group">
    <label class="p-form__label" for="input-optional">Label (optional)</label>
    <input
      type="text"
      name="input-optional"
      id="input-optional"
      class="p-form__input"
    />
  </div>
</fieldset>

Only ask for what’s needed

Only ever ask for information that is necessary. If something is not needed, do not ask it. If it might be needed in the future, update the form at a later date to include the question. This will reduce the need to include optional fields and save users’ time when completing forms.

Ask personal questions sensitively

Users may not want to provide information if:

  • they do not know why we are asking for it
  • they do not know what we will do with it
  • we do not ask in a sensitive way
  • it does not allow them to answer in a way that they want
  • it’s about a subject that’s hard for them

If you do need to ask for personal or sensitive information, explain why you are asking for it and word the question respectfully.

The NHS has useful guidance for asking sensitive questions.

Errors

Error handling

Only display error messages after a user submits the form or clicks to continue to the next step. Do not validate inputs as users are typing as it can cause stress and frustration.

If your product is already handling errors in a different way

If you work in Parliament and need advice on presenting errors in this way, contact the Improving User Experience team on the #design-system Slack channel.

Writing error messages

Error messages must explain what went wrong and how to fix it.

Make sure to follow the error message guidance and use specific error messages to help your users.

Where relevant we have included specific error messages in the guidelines for most of the form elements in the design system.

Help prevent errors

To reduce the need for users to have to fix errors, try to help them prevent errors occurring in the first place. You can do this by:

  • writing good questions
  • using hint text to explain any specific format requirements
  • letting users enter information in different format (for example, not making fields case sensitive)
  • allowing users to autofill information into text input using the autocomplete attributes

Things not to do

Placeholder text

Do not use placeholder text in place of a label or hint text as:

  • not all screen readers will read it out
  • it disappears when a user selects the input making it hard for them to remember what it said

Do not use the disabled state attribute

Do not use the disabled state attribute as it can cause issues for users. Disabled inputs are often not distinguishable from active ones, and they do not tell users why they cannot interact with them.

Instead, allow users access to all inputs, even if that means that after trying to submit or continue with a form it fails. Use error messages to then help users understand what they need to do to fix the problem. Using error messages also follows best practice guidance for creating accessible interfaces.

If users must submit information in a specific order, consider using a multistep form.

Displaying previously submitted information

Do not use the disabled state to display previously submitted information. This can confuse users as they may not realise that they cannot change the information.

Instead, consider displaying the information as standard text.

Progress indicators

Generally, progress indicators are not necessary and can cause issues because they:

  • are often not noticed
  • take up lots of space
  • do not scale well on small screens
  • can distract and confuse some users
  • make it hard to handle conditional sections

Start by testing your form without a progress indicator to see if it’s simple enough that users do not need one.

If it’s not, try changing the order, type or number of questions before adding a progress indicator. If people still have difficulty, try adding a simple step indicator. For example, ‘Page 1 of 3’.

<div>
  <span>Page 2 of 3</span>
</div>
<h1>Personal details</h1>

Have a question, suggestion or feedback?

The Improving User Experience cluster manages the design system.

If you work in Parliament, contact us on the #design-system Slack channel.