Form elements
-
Buttons
Use buttons to help users carry out an action on a page like starting an application or saving their progress.
WCAG 2.2 affects this component
To meet new success criteria introduced in the Web Content Accessibility Guidelines (WCAG) 2.2, make sure that users can successfully:
See the full list of design system changes to meet WCAG 2.2.
We have 3 buttons:
Primary button
There are 2 versions of the primary button: the default version and the reverse version.
<button class="nhsuk-button" data-module="nhsuk-button" type="submit">
Save and continue
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
text: "Save and continue"
}) }}
Use the reverse version on dark backgrounds.
<button class="nhsuk-button nhsuk-button--reverse" data-module="nhsuk-button" type="submit">
Save and continue
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
text: "Save and continue",
classes: "nhsuk-button--reverse"
}) }}
When to use a primary button
Use a primary button for the main call to action on a page, for example to help users start an application or save their progress.
Use only 1 primary button on a page. Having more than 1 reduces their impact and makes it harder for users to know what to do next.
More about when to use and not use buttons.
Secondary button
There are 2 versions of the secondary button.
By default, the secondary button is transparent and has no colour. Use it on the page background colour ($color_nhsuk-grey-5
).
<button class="nhsuk-button nhsuk-button--secondary" data-module="nhsuk-button" type="submit">
Find my location
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
text: "Find my location",
classes: "nhsuk-button--secondary"
}) }}
You can make the button white when you use it on darker backgrounds. Use the .nhsuk-button--secondary-solid
class to maintain colour contrast.
<button class="nhsuk-button nhsuk-button--secondary-solid" data-module="nhsuk-button" type="submit">
Find my location
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
text: "Find my location",
classes: "nhsuk-button--secondary-solid"
}) }}
When to use a secondary button
Use a secondary button either:
- for secondary actions on a page
- when an action needs less prominence, for example because it is optional
Pages with too many calls to action make it hard for users to know what to do next. Before adding lots of secondary buttons, try to simplify the page or break the content down across multiple pages.
More about when to use and not use buttons.
Warning button
<button class="nhsuk-button nhsuk-button--warning" data-module="nhsuk-button" type="submit">
Yes, delete this vaccine
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
"text": "Yes, delete this vaccine",
"classes": "nhsuk-button--warning"
}) }}
When to use a warning button
Warning buttons are designed to make users think carefully before they use them. They are only effective if used very sparingly. Most services should not need one.
Only use warning buttons for actions with serious destructive consequences that a user cannot easily undo. For example, permanently deleting an account.
For important destructive actions like this, include an additional step to confirm it. Use another style of button for the initial call to action, and a warning button for the final confirmation.
Do not only rely on the red colour of a warning button to communicate the serious nature of the action. This is because not all users will be able to see the colour or will understand what it means. Make sure the context and button text make clear what will happen if the user selects it.
When to use buttons
Use buttons to start transactional journeys and carry out actions, like saving information.
When not to use buttons
Do not use buttons as links:
- to pages which are not part of your user journey
- from 1 flat content page to another
- to external websites
Try not to have multiple buttons on a page. Follow GOV.UK guidance on structuring forms and starting with one thing per page.
How to use buttons
Write button text in sentence case, describing the action it performs. For example:
- "Start now" on the start page of your service
- "Log in" to an account a user has already created
- "Continue" whether the service saves or does not save a user's information
- "Save and continue" when the service saves a user's information but your research shows you need to reassure them that it does
- "Save and come back later" when a user can save their information and come back later
- "Add another" to add another item to a list or group
- "Pay" to make a payment
- "Confirm and send" on a Check answers page that does not have any legal content a user must agree to
- "Confirm and save" on a Check answers page on a staff-facing service or where data is not being sent to another person or system
- "Accept and send" on a Check answers page that has legal content a user must agree to
- "Log out" when a user is logged in to an account
You may need to include more or different words to better describe the action. For example, "Add another address" and "Accept and claim a tax refund".
Align the primary action button to the left edge of your form.
Do not decrease the height or target area of buttons. This is to make sure users can easily interact with buttons. This is to comply with WCAG 2.2 success criterion 2.5.8 Target Size (W3C).
Disabled buttons
Disabled buttons have poor contrast and can confuse some users. Only use them if user research shows it makes things easier for users to understand.
We have developed disabled versions of the 3 buttons but we haven't tested them yet. You can get the latest disabled button code in the NHS.UK frontend library in GitHub.
Colour contrast
All 4 buttons pass AA guidelines for colour contrast. The disabled versions of the buttons do not meet accessibility colour contrast ratios. If your team has discovered a user need for disabled buttons, use them carefully and test them with users with access needs.
Stop users from accidentally sending information more than once
Sometimes, users double click buttons because they:
- have used operating systems where they have to double click items to make them work
- are experiencing a slow connection which means they are not given feedback on their action quickly enough
- have motor impairments such as hand tremors which cause them to click the button involuntarily
In some cases, this can mean their information is sent twice.
For example, the GOV.UK Notify team discovered that a number of users were receiving invitations twice, because the person sending them was double clicking the "send" button.
If your research shows that users are frequently sending information twice, you can configure the button to ignore the 2nd click.
To do this, set the data-prevent-double-click
attribute to true
. You can do this directly in the HTML or, if you're using Nunjucks, you can use the Nunjucks macro as shown in this example.
<button class="nhsuk-button" data-module="nhsuk-button" data-prevent-double-click="true" type="submit">
Save and continue
</button>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
element | string | false | Whether to use an `input`, `button` or `a` element to create the button. In most cases you will not need to set this as it will be configured automatically if you use `href` or `html`. |
text | string | true | If `html` is set, this is not required. Text for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
html | string | true | If `text` is set, this is not required. HTML for the button or link. If `html` is provided, the `text` argument will be ignored and `element` will be automatically set to `button` unless `href` is also set, or it has already been defined. This argument has no effect if `element` is set to `input`. |
name | string | false | Name for the `input` or `button`. This has no effect on `a` elements. |
type | string | false | Type of `input` or `button` – `button`, `submit` or `reset`. Defaults to `submit`. This has no effect on `a` elements. |
value | string | false | Value for the `button` tag. This has no effect on `a` or `input` elements. |
disabled | boolean | false | Whether the button should be disabled. For button and input elements, `disabled` and `aria-disabled` attributes will be set automatically. |
href | string | false | The URL that the button should link to. If this is set, `element` will be automatically set to `a` if it has not already been defined. |
classes | string | false | Classes to add to the button component. |
attributes | object | false | HTML attributes (for example data attributes) to add to the button component. |
preventDoubleClick | boolean | false | Prevent accidental double clicks on submit buttons from submitting forms multiple times |
{% from 'button/macro.njk' import button %}
{{ button({
text: "Save and continue",
preventDoubleClick: true
}) }}
This feature will prevent double clicks for users that have JavaScript enabled. However, you should also think about the issue server-side to protect against attacks.
In the case of slow connections, aim to give the user information about what's happening, for example, by showing a loading spinner or a modal, before using data-prevent-double-click
.
Research
We based our buttons on the GOV.UK designs. But because our logo is a blue rectangle and a number of our components (including panel headings) have squared edges, we decided that GOV.UK buttons did not stand out enough. The square buttons did not look clickable next to the other square components.
We made the buttons more "buttony" by rounding the corners (adding corner radiuses). There is research to suggest that rounded corners make things more clickable.
Our testing confirmed this. Users were able to complete tasks using buttons and they did not confuse them with non-clickable components.
Help us improve this guidance
Share insights or feedback and take part in the discussion. We use GitHub as a collaboration space. All the information on it is open to the public.
Read more about how to feedback or share insights.
If you have any questions, get in touch with the service manual team.
Updated: May 2025