Pages

Question pages

This pattern explains when to use question pages and what elements they need to include.

<div class="govuk-width-container">
  <a href="#" class="govuk-back-link">Back</a>

  <main class="govuk-main-wrapper " id="main-content" role="main">
    <div class="govuk-grid-row">
      <div class="govuk-grid-column-two-thirds">
        <form action="/form-handler" method="post" novalidate>

          <div class="govuk-form-group">
            <fieldset class="govuk-fieldset" aria-describedby="dob-hint" role="group">
              <legend class="govuk-fieldset__legend govuk-fieldset__legend--xl">
                <h1 class="govuk-fieldset__heading">
                  What is your date of birth?
                </h1>
              </legend>
              <span id="dob-hint" class="govuk-hint">
                For example, 31 3 1980
              </span>
              <div class="govuk-date-input" id="dob">
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="dob-day">
                      Day
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="dob-day" name="dob-day" type="number" pattern="[0-9]*">
                  </div>
                </div>
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="dob-month">
                      Month
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="dob-month" name="dob-month" type="number" pattern="[0-9]*">
                  </div>
                </div>
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="dob-year">
                      Year
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-4" id="dob-year" name="dob-year" type="number" pattern="[0-9]*">
                  </div>
                </div>
              </div>
            </fieldset>
          </div>

          <button type="submit" class="govuk-button">
            Continue
          </button>
        </form>
      </div>
    </div>
  </main>
</div>
{% from "back-link/macro.njk" import govukBackLink %}
{% from "date-input/macro.njk" import govukDateInput %}
{% from "button/macro.njk" import govukButton %}

{% block beforeContent %}
  {{ govukBackLink({
    text: "Back"
  }) }}
{% endblock %}

{% block content %}
  <div class="govuk-grid-row">
    <div class="govuk-grid-column-two-thirds">
      <form action="/form-handler" method="post" novalidate>
        {{ govukDateInput({
          id: "dob",
          namePrefix: "dob",
          fieldset: {
            legend: {
              text: "What is your date of birth?",
              isPageHeading: true,
              classes: "govuk-fieldset__legend--xl"
            }
          },
          hint: {
            text: "For example, 31 3 1980"
          }
        }) }}

        {{ govukButton({
          text: "Continue"
        }) }}
      </form>
    </div>
  </div>
{% endblock %}

When to use this pattern

Follow this pattern whenever you need to ask users questions within your service.

How it works

Question pages must include a:

  • back link
  • page heading
  • continue button

If research shows it’s helpful for users, you can also include a progress indicator.

Always include a back link on question pages.

Some users don’t trust browser ‘back’ buttons when they’re entering data. Add a back link to reassure users that it’s possible to go back and change previous answers.

The back link should be at the top of the page because users are most likely to want to go back when they first land on a page.

Make sure the back link takes users to the previous page and that it still works when JavaScript isn’t available.

Page headings

Page headings can be statements or questions.

If you’re only asking for one piece of information on a page, make the question the page heading.

For example:

<div class="govuk-width-container">
  <a href="#" class="govuk-back-link">Back</a>

  <main class="govuk-main-wrapper " id="main-content" role="main">
    <div class="govuk-grid-row">
      <div class="govuk-grid-column-two-thirds">
        <form action="/form-handler" method="post" novalidate>
          <div class="govuk-form-group">
            <h1 class="govuk-label-wrapper">
              <label class="govuk-label govuk-label--xl" for="postcode">
                What is your home postcode?
              </label>

            </h1>
            <input class="govuk-input govuk-input--width-10" id="postcode" name="postcode" type="text">
          </div>

          <button type="submit" class="govuk-button">
            Continue
          </button>
        </form>
      </div>
    </div>
  </main>
</div>
{% from "back-link/macro.njk" import govukBackLink %}
{% from "input/macro.njk" import govukInput %}
{% from "button/macro.njk" import govukButton %}

{% block beforeContent %}
  {{ govukBackLink({
    text: "Back"
  }) }}
{% endblock %}

{% block content %}
<div class="govuk-grid-row">
  <div class="govuk-grid-column-two-thirds">
    <form action="/form-handler" method="post" novalidate>
      {{ govukInput({
        label: {
          text: "What is your home postcode?",
          isPageHeading: true,
          classes: "govuk-label--xl"
        },
        classes: "govuk-input--width-10",
        id: "postcode",
        name: "postcode"
      }) }}

      {{ govukButton({
        text: "Continue"
      }) }}
    </form>
  </div>
</div>
{% endblock %}

If you need to ask for multiple related things on a page, use a statement as the heading.

For example:

<div class="govuk-width-container">
  <a href="#" class="govuk-back-link">Back</a>

  <main class="govuk-main-wrapper " id="main-content" role="main">
    <div class="govuk-grid-row">
      <div class="govuk-grid-column-two-thirds">
        <h1 class="govuk-heading-xl">Passport details</h1>

        <form action="/form-handler" method="post" novalidate>

          <div class="govuk-form-group">
            <label class="govuk-label govuk-label--m" for="passport-number">
              Passport number
            </label>
            <span id="passport-number-hint" class="govuk-hint">
              For example, 502135326
            </span>
            <input class="govuk-input" id="passport-number" name="passport-number" type="text" aria-describedby="passport-number-hint">
          </div>

          <div class="govuk-form-group">
            <fieldset class="govuk-fieldset" aria-describedby="expiry-hint" role="group">
              <legend class="govuk-fieldset__legend govuk-fieldset__legend--m"> Expiry date
              </legend>
              <span id="expiry-hint" class="govuk-hint">
                For example, 31 3 1980
              </span>
              <div class="govuk-date-input" id="expiry">
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="expiry-day">
                      Day
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="expiry-day" name="expiry-day" type="number" pattern="[0-9]*">
                  </div>
                </div>
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="expiry-month">
                      Month
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-2" id="expiry-month" name="expiry-month" type="number" pattern="[0-9]*">
                  </div>
                </div>
                <div class="govuk-date-input__item">
                  <div class="govuk-form-group">
                    <label class="govuk-label govuk-date-input__label" for="expiry-year">
                      Year
                    </label>
                    <input class="govuk-input govuk-date-input__input govuk-input--width-4" id="expiry-year" name="expiry-year" type="number" pattern="[0-9]*">
                  </div>
                </div>
              </div>
            </fieldset>
          </div>

          <button type="submit" class="govuk-button">
            Continue
          </button>

        </form>
      </div>
    </div>
  </main>
</div>
{% from "back-link/macro.njk" import govukBackLink %}
{% from "input/macro.njk" import govukInput %}
{% from "date-input/macro.njk" import govukDateInput %}
{% from "button/macro.njk" import govukButton %}

{% block beforeContent %}
  {{ govukBackLink({
    text: "Back"
  }) }}
{% endblock %}

{% block content %}
  <div class="govuk-grid-row">
    <div class="govuk-grid-column-two-thirds">
      <h1 class="govuk-heading-xl">Passport details</h1>

      <form action="/form-handler" method="post" novalidate>

        {{ govukInput({
          label: {
            text: "Passport number",
            classes: "govuk-label--m"
          },
          hint: {
            text: "For example, 502135326"
          },
          id: "passport-number",
          name: "passport-number"
        }) }}

        {{ govukDateInput({
          id: "expiry",
          namePrefix: "expiry",
          fieldset: {
            legend: {
              text: "Expiry date",
              classes: "govuk-fieldset__legend--m"
            }
          },
          hint: {
            text: "For example, 31 3 1980"
          }
        }) }}

        {{ govukButton({
          text: "Continue"
        }) }}

      </form>
    </div>
  </div>
{% endblock %}

Don’t duplicate the same page heading across multiple pages.

The page heading should relate specifically to the information being asked for on the current page, not any higher-level section the page is part of.

If you need to show the high-level section, you can use the govuk-caption style.

For example, ‘About you’:

<span class="govuk-caption-xl">About you</span>
<h1 class="govuk-heading-xl">
  What is your home address?
</h1>

Continue button

Make sure your ‘Continue’ button is:

  • labelled ‘Continue’, not ‘Next’
  • aligned to the left so users don’t miss it

Using progress indicators

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

Try improving the order, type or number of questions before adding a progress indicator. If people still have difficulty, try adding a simple step or question indicator like this one.

<span class="govuk-caption-xl">Question 3 of 9</span>
<h1 class="govuk-heading-xl">
  Your details
</h1>
<span class="govuk-caption-xl">Question 3 of 9</span>
<h1 class="govuk-heading-xl">
 Your details
</h1>

Only include the total number of questions if you can do so reliably. As the user moves through the form, make sure the indicator updates to tell them which question they are on and the total number remaining.

Don’t use progress indicators that do all of the following:

  • show all questions at once
  • allow navigation to previous questions
  • show the current question

An example of this looks like:

Screenshot of a progress indicator that shows five questions.

These can be problematic because they:

  • are often not noticed
  • take up lots of space
  • don’t scale well on small screens
  • can distract and confuse some users
  • make it hard to write good labels for the steps
  • make it hard to handle conditional sections

A number of GOV.UK services have removed this style of progress indicator without any negative effects. Read a blog post about how the Carer’s Allowance team removed a 12-step progress indicator with no effect on completion rates or times.

Start by asking one question per page

Asking just one question per question page helps users understand what you’re asking them to do, and focus on the specific question and its answer.

To help you follow this approach, you can set the contents of a <legend> or <label> for a page’s input as the page heading. This is good practice as it means that users of screen readers will only hear the contents once.

Read more about why and how to set labels and legends as headings.

You can also learn more about how starting with one thing per page helps users in the GOV.UK Service Manual.

Asking users questions

You should make sure you know why you’re asking every question and only ask users for information you really need.

To help you work out what to ask, you can carry out a question protocol.

If you ask for optional information, mark the labels of optional fields with ‘(optional)’. Don’t mark mandatory fields with asterisks.

On every question page you should:

  • make sure it’s clear to users why you’re asking each question
  • allow users to answer ‘I don’t know’ or ‘I’m not sure’ if they are valid responses

Research on this pattern

If you’ve used this pattern, get in touch to share your user research findings.

Get in touch

If you’ve got a question, idea or suggestion share it in #govuk-design-system on cross-government Slack (open in app) or email the Design System team on govuk-design-system-support@digital.cabinet-office.gov.uk

Discuss ‘Question pages’ on GitHub