Styles
Forms
Allow users to enter information, search for content or perform tasks.
Contents
User-submitted data
Allow users to enter data using:
Do not use the date search or select components in forms designed for users to submit data for storage.
HTML
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create a record</h1>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="record_name">
Enter the name of the record
</label>
</h2>
</div>
<input type="text" id="record_name" class="tna-text-input " name="name" value="" spellcheck="false">
</div>
<div class="tna-form__group">
<fieldset class="tna-form__fieldset">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Select the record categories
</h2>
</legend>
<div class="tna-checkboxes" id="record_categories">
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-architectural" value="architectural" name="categories">
<label for="record_categories-architectural" class="tna-checkboxes__item-label">
Architectural
</label>
</div>
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-banking" value="banking" name="categories">
<label for="record_categories-banking" class="tna-checkboxes__item-label">
Banking
</label>
</div>
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-charities" value="charities" name="categories">
<label for="record_categories-charities" class="tna-checkboxes__item-label">
Charities
</label>
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group">
<fieldset class="tna-form__fieldset">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Enter the start date of the record
</h2>
</legend>
<div class="tna-date-input" id="record_date">
<div class="tna-date-input__item">
<label for="record_date-day" class="tna-date-input__item-label">
Day
</label>
<input type="text" id="record_date-day" value="" name="date-day" class="tna-date-input__item-input" inputmode="numeric">
</div>
<div class="tna-date-input__item">
<label for="record_date-month" class="tna-date-input__item-label">
Month
</label>
<input type="text" id="record_date-month" value="" name="date-month" class="tna-date-input__item-input" inputmode="numeric">
</div>
<div class="tna-date-input__item">
<label for="record_date-year" class="tna-date-input__item-label">
Year
</label>
<input type="text" id="record_date-year" value="" name="date-year" class="tna-date-input__item-input tna-date-input__item-input--wider" inputmode="numeric">
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group">
<fieldset class="tna-form__fieldset">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Select the type of record
</h2>
</legend>
<div class="tna-radios" id="record_type">
<div class="tna-radios__item">
<input type="radio" id="record_type-physical" value="physical" name="type">
<label for="record_type-physical" class="tna-radios__item-label">
Physical
</label>
</div>
<div class="tna-radios__item">
<input type="radio" id="record_type-digital" value="digital" name="type">
<label for="record_type-digital" class="tna-radios__item-label">
Digital
</label>
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="record_feedback">
Enter the record description
</label>
</h2>
</div>
<textarea id="record_feedback" class="tna-textarea " name="feedback" spellcheck="false" rows="5"></textarea>
</div>
<div class="tna-button-group">
<button class="tna-button" type="submit">
Create record
</button>
<button class="tna-button tna-button--plain" type="reset">
Clear
</button>
</div>
</form>
</div>
</div>
Nunjucks
{% from "nationalarchives/components/button/macro.njk" import tnaButton %}
{% from "nationalarchives/components/checkboxes/macro.njk" import tnaCheckboxes %}
{% from "nationalarchives/components/date-input/macro.njk" import tnaDateInput %}
{% from "nationalarchives/components/radios/macro.njk" import tnaRadios %}
{% from "nationalarchives/components/textarea/macro.njk" import tnaTextarea %}
{% from "nationalarchives/components/text-input/macro.njk" import tnaTextInput %}
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create a record</h1>
{{ tnaTextInput({
label: "Enter the name of the record",
headingLevel: 2,
headingSize: "m",
id: "record_name",
name: "name"
}) }}
{{ tnaCheckboxes({
label: "Select the record categories",
headingLevel: 2,
headingSize: "m",
id: "record_categories",
name: "categories",
items: [
{
text: "Architectural",
value: "architectural"
},
{
text: "Banking",
value: "banking"
},
{
text: "Charities",
value: "charities"
}
]
}) }}
{{ tnaDateInput({
label: "Enter the start date of the record",
headingLevel: 2,
headingSize: "m",
id: "record_date",
name: "date"
}) }}
{{ tnaRadios({
label: "Select the type of record",
headingLevel: 2,
headingSize: "m",
id: "record_type",
name: "type",
items: [
{
text: "Physical",
value: "physical"
},
{
text: "Digital",
value: "digital"
}
]
}) }}
{{ tnaTextarea({
label: "Enter the record description",
headingLevel: 2,
headingSize: "m",
id: "record_feedback",
name: "feedback"
}) }}
<div class="tna-button-group">
{{ tnaButton({
text: "Create record",
buttonElement: true,
buttonType: "submit"
}) }}
{{ tnaButton({
text: "Clear",
buttonElement: true,
buttonType: "reset",
plain: true
}) }}
</div>
</form>
</div>
</div>
Displaying errors
Follow GOV.UK advice on recovering from validation errors.
Use the error summary component to summarise the issues and provide links directly to the problem fields.
HTML
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create a record</h1>
<div class="tna-error-summary" data-module="tna-error-summary" data-disableautofocus="true">
<div role="alert">
<h2 class="tna-error-summary__heading tna-heading-m">
There is a problem
</h2>
<ul class="tna-error-summary__list">
<li class="tna-error-summary__item">
<a href="#record_name" class="tna-error-summary__link">The record name cannot contain emojis</a>
</li>
<li class="tna-error-summary__item">
<a href="#record_categories" class="tna-error-summary__link">Select at least one category</a>
</li>
<li class="tna-error-summary__item">
<a href="#record_date" class="tna-error-summary__link">The date of the record cannot be in the future</a>
</li>
<li class="tna-error-summary__item">
<a href="#record_type" class="tna-error-summary__link">Select the type of record</a>
</li>
<li class="tna-error-summary__item">
<a href="#record_description" class="tna-error-summary__link">The record description cannot be blank</a>
</li>
</ul>
</div>
</div>
<div class="tna-form__group tna-form__group--error">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="record_name">
Enter the name of the record
</label>
</h2>
<p id="record_name-error" class="tna-form__error-message">
<span class="tna-!--visually-hidden">Error:</span> The record name cannot contain emojis
</p>
</div>
<input type="text" id="record_name" class="tna-text-input " name="name" value="😎" spellcheck="false" aria-describedby=" record_name-error">
</div>
<div class="tna-form__group tna-form__group--error">
<fieldset class="tna-form__fieldset" aria-describedby=" record_categories-error">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Select the record categories
</h2>
</legend>
<p id="record_categories-error" class="tna-form__error-message">
<span class="tna-!--visually-hidden">Error:</span> Select at least one category
</p>
<div class="tna-checkboxes" id="record_categories">
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-architectural" value="architectural" name="categories">
<label for="record_categories-architectural" class="tna-checkboxes__item-label">
Architectural
</label>
</div>
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-banking" value="banking" name="categories">
<label for="record_categories-banking" class="tna-checkboxes__item-label">
Banking
</label>
</div>
<div class="tna-checkboxes__item">
<input type="checkbox" id="record_categories-charities" value="charities" name="categories">
<label for="record_categories-charities" class="tna-checkboxes__item-label">
Charities
</label>
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group tna-form__group--error">
<fieldset class="tna-form__fieldset" aria-describedby=" record_date-error">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Enter the start date of the record
</h2>
</legend>
<p id="record_date-error" class="tna-form__error-message">
<span class="tna-!--visually-hidden">Error:</span> The date of the record cannot be in the future
</p>
<div class="tna-date-input" id="record_date">
<div class="tna-date-input__item">
<label for="record_date-day" class="tna-date-input__item-label">
Day
</label>
<input type="text" id="record_date-day" value="24" name="date-day" class="tna-date-input__item-input" inputmode="numeric">
</div>
<div class="tna-date-input__item">
<label for="record_date-month" class="tna-date-input__item-label">
Month
</label>
<input type="text" id="record_date-month" value="09" name="date-month" class="tna-date-input__item-input" inputmode="numeric">
</div>
<div class="tna-date-input__item">
<label for="record_date-year" class="tna-date-input__item-label">
Year
</label>
<input type="text" id="record_date-year" value="2086" name="date-year" class="tna-date-input__item-input tna-date-input__item-input--wider" inputmode="numeric">
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group tna-form__group--error">
<fieldset class="tna-form__fieldset" aria-describedby=" record_type-error">
<legend class="tna-form__legend">
<h2 class="tna-form__heading tna-form__heading--m">
Select the type of record
</h2>
</legend>
<p id="record_type-error" class="tna-form__error-message">
<span class="tna-!--visually-hidden">Error:</span> Select the type of record
</p>
<div class="tna-radios" id="record_type">
<div class="tna-radios__item">
<input type="radio" id="record_type-physical" value="physical" name="type">
<label for="record_type-physical" class="tna-radios__item-label">
Physical
</label>
</div>
<div class="tna-radios__item">
<input type="radio" id="record_type-digital" value="digital" name="type">
<label for="record_type-digital" class="tna-radios__item-label">
Digital
</label>
</div>
</div>
</fieldset>
</div>
<div class="tna-form__group tna-form__group--error">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="record_description">
Enter the record description
</label>
</h2>
<p id="record_description-error" class="tna-form__error-message">
<span class="tna-!--visually-hidden">Error:</span> The record description cannot be blank
</p>
</div>
<textarea id="record_description" class="tna-textarea " name="description" spellcheck="false" rows="5" aria-describedby=" record_description-error"></textarea>
</div>
<div class="tna-button-group">
<button class="tna-button" type="submit">
Create record
</button>
<button class="tna-button tna-button--plain" type="reset">
Clear
</button>
</div>
</form>
</div>
</div>
Nunjucks
{% from "nationalarchives/components/button/macro.njk" import tnaButton %}
{% from "nationalarchives/components/checkboxes/macro.njk" import tnaCheckboxes %}
{% from "nationalarchives/components/date-input/macro.njk" import tnaDateInput %}
{% from "nationalarchives/components/error-summary/macro.njk" import tnaErrorSummary %}
{% from "nationalarchives/components/radios/macro.njk" import tnaRadios %}
{% from "nationalarchives/components/textarea/macro.njk" import tnaTextarea %}
{% from "nationalarchives/components/text-input/macro.njk" import tnaTextInput %}
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create a record</h1>
{{ tnaErrorSummary({
title: "There is a problem",
headingLevel: 2,
items: [
{
text: "The record name cannot contain emojis",
href: "#record_name"
},
{
text: "Select at least one category",
href: "#record_categories"
},
{
text: "The date of the record cannot be in the future",
href: "#record_date"
},
{
text: "Select the type of record",
href: "#record_type"
},
{
text: "The record description cannot be blank",
href: "#record_description"
}
],
disableAutoFocus: true
}) }}
{{ tnaTextInput({
label: "Enter the name of the record",
headingLevel: 2,
headingSize: "m",
id: "record_name",
name: "name",
value: "😎",
error: {
text: "The record name cannot contain emojis"
}
}) }}
{{ tnaCheckboxes({
label: "Select the record categories",
headingLevel: 2,
headingSize: "m",
id: "record_categories",
name: "categories",
items: [
{
text: "Architectural",
value: "architectural"
},
{
text: "Banking",
value: "banking"
},
{
text: "Charities",
value: "charities"
}
],
error: {
text: "Select at least one category"
}
}) }}
{{ tnaDateInput({
label: "Enter the start date of the record",
headingLevel: 2,
headingSize: "m",
id: "record_date",
name: "date",
value: {
day: "24",
month: "09",
year: "2086"
},
error: {
text: "The date of the record cannot be in the future"
}
}) }}
{{ tnaRadios({
label: "Select the type of record",
headingLevel: 2,
headingSize: "m",
id: "record_type",
name: "type",
items: [
{
text: "Physical",
value: "physical"
},
{
text: "Digital",
value: "digital"
}
],
error: {
text: "Select the type of record"
}
}) }}
{{ tnaTextarea({
label: "Enter the record description",
headingLevel: 2,
headingSize: "m",
id: "record_description",
name: "description",
error: {
text: "The record description cannot be blank"
}
}) }}
<div class="tna-button-group">
{{ tnaButton({
text: "Create record",
buttonElement: true,
buttonType: "submit"
}) }}
{{ tnaButton({
text: "Clear",
buttonElement: true,
buttonType: "reset",
plain: true
}) }}
</div>
</form>
</div>
</div>
User accounts
Use the autocomplete
property to help people fill in forms with their own data. See the list of input purposes on w3.org.
HTML
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create an account</h1>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="firstname">
Enter your first name
</label>
</h2>
</div>
<input type="text" id="firstname" class="tna-text-input " name="firstname" value="" spellcheck="false">
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="surname">
Enter your last name
</label>
</h2>
</div>
<input type="text" id="surname" class="tna-text-input " name="surname" value="" spellcheck="false">
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="email">
Enter your email address
</label>
</h2>
</div>
<input type="text" id="email" class="tna-text-input " name="email" value="" spellcheck="false">
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="country">
Enter your country
</label>
</h2>
</div>
<input type="text" id="country" class="tna-text-input " name="country" value="" spellcheck="false">
</div>
<div class="tna-button-group">
<button class="tna-button" type="submit">
Create record
</button>
<button class="tna-button tna-button--plain" type="reset">
Clear
</button>
</div>
</form>
</div>
</div>
Nunjucks
{% from "nationalarchives/components/button/macro.njk" import tnaButton %}
{% from "nationalarchives/components/text-input/macro.njk" import tnaTextInput %}
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<h1 class="tna-heading-xl">Create an account</h1>
{{ tnaTextInput({
label: "Enter your first name",
headingLevel: 2,
headingSize: "m",
id: "firstname",
name: "firstname",
autocomplete: "given-name"
}) }}
{{ tnaTextInput({
label: "Enter your last name",
headingLevel: 2,
headingSize: "m",
id: "surname",
name: "surname",
autocomplete: "family-name"
}) }}
{{ tnaTextInput({
label: "Enter your email address",
headingLevel: 2,
headingSize: "m",
id: "email",
name: "email",
autocomplete: "email"
}) }}
{{ tnaTextInput({
label: "Enter your country",
headingLevel: 2,
headingSize: "m",
id: "country",
name: "country",
autocomplete: "country"
}) }}
<div class="tna-button-group">
{{ tnaButton({
text: "Create record",
buttonElement: true,
buttonType: "submit"
}) }}
{{ tnaButton({
text: "Clear",
buttonElement: true,
buttonType: "reset",
plain: true
}) }}
</div>
</form>
</div>
</div>
Searching
Avoid allowing forms that are used for searching to produce errors.
Searching for dates should use the date search component. Using this component should mean that there is less chance of producing an error.
Use the select component to offer simple options for sorting.
HTML
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
<div class="tna-search-field">
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h1 class="tna-form__heading tna-form__heading--l">
<label class="tna-form__label" for="search">
Search for a record
</label>
</h1>
</div>
<div class="tna-search-field__fields">
<input type="search" id="search" class="tna-search-field__input " name="q" value="" spellcheck="false">
<button type="submit" class="tna-button tna-search-field__button">
Search
<i class="fa-solid fa-fw fa-arrow-right tna-!--hide-on-tiny" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="date">
Earliest record date
</label>
</h2>
</div>
<input type="date" id="date" class="tna-date-search " name="date" value="">
</div>
<div class="tna-form__group">
<div class="tna-form__group-contents">
<h2 class="tna-form__heading tna-form__heading--m">
<label class="tna-form__label" for="sort">
Sort by
</label>
</h2>
</div>
<select class="tna-select " name="sort" id="sort">
<option value="relevance">Relevance</option>
<option value="date">Date</option>
<option value="title">Title</option>
</select>
</div>
<div class="tna-button-group">
<button class="tna-button" type="submit">
Update results
</button>
</div>
</form>
</div>
</div>
Nunjucks
{% from "nationalarchives/components/button/macro.njk" import tnaButton %}
{% from "nationalarchives/components/date-search/macro.njk" import tnaDateSearch %}
{% from "nationalarchives/components/select/macro.njk" import tnaSelect %}
{% from "nationalarchives/components/search-field/macro.njk" import tnaSearchField %}
<div class="tna-container">
<div class="tna-column tna-column--full tna-!--padding-vertical-m">
<form novalidate>
{{ tnaSearchField({
label: "Search for a record",
headingLevel: 1,
headingSize: "l",
id: "search",
name: "q"
}) }}
{{ tnaDateSearch({
label: "Earliest record date",
headingLevel: 2,
headingSize: "m",
id: "date",
name: "date"
}) }}
{{ tnaSelect({
label: "Sort by",
headingLevel: 2,
headingSize: "m",
id: "sort",
name: "sort",
items: [
{
text: "Relevance",
value: "relevance"
},
{
text: "Date",
value: "date"
},
{
text: "Title",
value: "title"
}
]
}) }}
<div class="tna-button-group">
{{ tnaButton({
text: "Update results",
buttonElement: true,
buttonType: "submit"
}) }}
</div>
</form>
</div>
</div>
Background colours
Don't use forms within sections that use either accent or light accent block colours. Use only regular, tinted or contrasting backgrounds.