Software Engineer or Frontend Developer
As a Software Engineer or Frontend Developer, you have one of the most important roles when it comes to accessibility. A design can have considered accessibility, but it’s up to you to build it to work correctly.
By using existing libraries and frameworks such as GOV.UK Frontend and DWP CASA, you can get a lot of good practices for accessibility built in, however we need to be mindful of how we apply them.
Using GOV.UK Frontend does not mean your service automatically meets level AA of WCAG 2.1. You’ll still need to make sure your service as a whole meets accessibility requirements.
If you want to see how your code test with assistive technology, you can use our assistive technology testing templates
Working with others
You will also want to work with QA Testers to make sure automated processes are in place for checking things with tools like aXe and putting in place accessibility criteria are part of your definition of done.
Things to consider as a Software Engineer or Frontend Developer
Alternative text for non-text content
If the content contains images or other non-text content such as graphs or charts, then you need to define what the alt attribute should be.
If an image is purely decorative then you need to provide an empty alt attribute so that it is hidden from screenreaders. However, if the image adds context to the content, then it should have a description.
Example of a decorative image:
<img src="patterned-background.jpg" alt="" />
Example of an image which needs context:
<img src="cat.jpg" alt="A cat wearing sunglasses." />
You should work with an Interaction Designer and a Content Designer to make sure alternative text is provided for images that need it.
Announce dynamic content
If the content of a page changes dynamically, such as a pop-up or using live data, you must announce the changes to a screenreader.
Usually this would be done using the aria-live attributes. Adding aria-live to an element will tell the screenreader that it needs to monitor that content because it is likely to change at some point.
For example, if you have a live chat function, the screenreader would need to know every time a new message was available. By adding aria-live to the chat window, every time you append something to it the screenreader will read it out. By setting it to polite, it means the screenreader will finish anything it is already reading before reading out the appended message.
<div id="chat-window" aria-live="polite"> <p> Hello, how can I assist you? </p> </div>
You can read more about aria on MDN.
Content and focus order
The content and the focus order needs to be logical. You should not use CSS to rearrange the content on the page to read in a different order to the way it is presented in the DOM. If you turn the CSS off, the page should read in the same order as it would if the CSS is turned on.
The focus order is also important. When tabbing through the page it should be obvious where the focus will go next. A logical order means the focus is always moving left to right and top to bottom within each section, and left to right and top to bottom between each section.
Cookie consent is part of of the General Data Protection Regulations (GDPR) and not strictly an accessibility issue. However a lot of the time cookie consent is presented in pop-up or banner form, and this can make your site inaccessible.
Here are some examples of how your cookie banner could make your site inaccessible:
- The cookie consent is a pop-up which is not announced to a screenreader. This fails WCAG 4.1.2 Name, Role, Value.
- The cookie consent is a pop-up which is cannot be navigated by keyboard. This fails WCAG 2.1.1 Keyboard.
- The cookie consent is a pop-up and the keyboard focus can disappear behind it. This fails 2.4.7 Focus visible.
- The cookie consent is presented as a banner at the bottom of the page but is the first content made available to keyboard focus or screenreaders. This fails WCAG 1.3.2 Meaningful sequence.
- The cookie consent uses links which are styled to look like buttons but cannot be programmatically determined to be buttons. This fails WCAG 4.1.2 Name, Role, Value
For any elements on the page, they should use the correct HTML tags. If you absolutely must use a different tag than would usually be expected, then you need to assign it the correct role. This allows assistive technology to still interact with the element as if the correct tag were used.
A common example of this is styling links to look like buttons. We should not really do this anyway as it makes user interfaces hard to predict. Links should navigate between pages and buttons should interact with data, such as submitting a form. However there might be some instances where research shows that a link needs to be more visible, such as a call to action.
<a href="/apply-now" class="btn" role="button">Apply now</a>
By giving the link a role of button, it can now be determined to be a button. So if somebody is using voice recognition software such as Dragon, when they say “click button”, Dragon will be able to find it on the page.
You can read more about aria roles on MDN.
DWP CASA framework
It ships with GOV.UK Frontend built in and will give you additional features such as routing logic, validation helpers, session management and protection against common security vulnerabilities.
If you’re building a NodeJS project in DWP, it is recommended you use the DWP CASA framework.
Existing patterns and components
These components often have accessibility considerations built in, so it’s not enough to just style your components to look similar.
You should work with an Interaction Designer to understand what parts of the design exist already. If you need to build something from scratch you will need to do additional work to make sure it’s accessible.
If you’re building a service for GOV.UK then you will need to use GOV.UK Frontend, and you will need to use version 3.0 or newer as older versions are not WCAG 2.1 compliant.
If you’re building a service for internal use or some other purpose, you might still want to consider using GOV.UK Frontend because it gives you a lot of styles and components that are accessible and WCAG 2.1 AA.
GOV.UK Frontend comes with templates and style sheets. It comes with accessible considerations built in such as colours, line-heights, letter spacing and responsive layouts. It will also allow you to use any of the components in the GOV.UK Design System.
You can use the templates in an unbranded mode. So even if you want to brand your website or service differently, you can still get all of the benefits of using GOV.UK Frontend.
If you choose not to use GOV.UK Frontend, then it’s likely you will need to do additional work both in development and testing.
Always use the correct heading levels.
A heading can have any level from H1 to H6. However, each heading level should relate to all the headings above it. The higher the number the more detail on the topic you should be going into.
For example, your might have a page to provide information on COVID-19. On that page you might have a section for information on how to protect yourself, and you might have another sections getting tested.
<h1>Stop the spread of COVID-19</h1> <h2>How to stay safe</h2> <h3>Wearing a mask</h3> <h3>Washing your hands</h3> <h3>Social distancing</h3> <h2>How to get a test</h2> <h3>Getting tested if you're a key worker</h3> <h3>Getting a test for somebody in a care home</h3>
If you need to change the size of the heading, use a different class to style it rather than changing the heading level itself.
<h1 class="govuk-heading-s">This is a small H1</h1> <h2 class="govuk-heading-l">This is a large H2</h2>
Inputs and labels
All form inputs need labels. It is not acceptable to have a form input without one, and trying to make them too fancy can make them inaccessible.
Any input without a label will fail WCAG 3.3.2 Labels or Instructions. A label should be explicit and should link the for attribute on the label to the id attribute of the input. This way the user has a larger target size and it is always clear which field the label is related to.
You should not use placeholder text instead of a label. A label should describe instruction for the input, and placeholder text should be reserved for an example if it is needed. If you use placeholder text instead of a label, you cannot then check what you entered against the instructions without deleting it back out the field.
<label for="reference">Enter your reference</label> <input id="reference" placeholder="ABC-123-123" name="reference" type="text" />
Every interactive element on the page needs to be accessible to a keyboard. This means you should be able to press the tab and arrow keys to navigate links, form inputs and submit buttons without any issues.
The focus must be visible at all times when using a keyboard. This means it must never focus anything which is off the page or obscured by another element. It must also be styled in a way so that it has enough contrast between any text and the background.
If you’re using GOV.UK Frontend, you will need to be using version 3.0 or newer to get the compliant focus styles. The old versions will fail WCAG on focus contrast. You can read more about the updated GOV.UK styles in the following GDS blog post: We’ve made the GDS Design System more accessible .
Links make sense out of context
For any link, remove everything else on the page and make sure it still makes sense. For example “Change” is not clear when you view it in isolation, but “Change bank details” is.
If you need to, you can use visually hidden text to add context to a link. This is text which is still read out by a screen reader but cannot be seen on the screen. For example:
<a href="#"> Change <span class="govuk-visually-hidden">bank details</span> </a>
Never use a link which tells the user to “Click here”. The word “click” makes an assumption that a mouse is being used, but the user could be using a keyboard or some form of assistive technology.
You should work with a Content Designer to make sure all links make sense out of context.
No keyboard traps
A keyboard user must be able to enter and exit sections without ever needing to use a mouse.
For example, if the user enters a pop-up window, but cannot focus the close button to exit the pop-up, this would be a keyboard trap.
Another example is a social media feed which uses an infinity scroll mechanism to constantly load in more posts as you near the bottom of the section. This could potentially trap the keyboard user from ever reaching the content beyond it.
The easiest way to check this is just to use the tab and arrow keys to interact with every part of the page. If at any point you need to refresh the page to get out of something, then this would be a fail.
Orientation and reflow
Every page must work regardless of the orientation of the device. This means switching between portrait and landscape should not cause any parts of the site to break.
The content should reflow if you scale the size of the window, and at no point should any text become unreadable at a minimum of 256px wide.
No items should scroll horizontally unless meaning would be lost otherwise. For example, an image or a complex data table.
Titles should describe the topic or purpose of the page.
The standard format for titles on a service is to set the context in 3 parts and separate them using en dashes (not hyphens). The 3 parts are:
‘Page context – Service context – Domain context`.
<title>What is your name? – Apply for Universal Credit – GOV.UK</title>
Page context should describe the topic or purpose of the page. They are usually identical to the H1, apart from when the H1 contains identifiable information.
For example, if the H1 is “What is your date of birth?” then the title would be the same.
However, sometimes the H1 can contain personal information, for example “What is John Smith’s date of birth”. In this case, the title should not be the same as there is a risk the information would be sent as analytics data.
In cases like this, the title should be as close as possible but not identical. For example, “What is your partners date of birth?”.
If there are errors on the page, then the page context part of the title should be prefixed with
Error:. You can read more about this on the GOV.UK pattern for validation errors.
You should work with a Content Designer and QA Tester to make sure the titles are correct when deciding if the page is finished.
It should be clear from the URL what the purpose of the page is. URLs are often overlooked as something that should be designed. But they’re an important part of accessibility as they can orientate users. They can also make content easier to find if a user needs to come back at a later date.
An example of a good url:
An example of a bad url:
You should work with a Content Designer to make sure when the the URLs follow the most helpful format for the user.
Setting the language
The language of a page should be set. This allows browsers to render the correct content, but it also allows assistive technologies to be able to pronounce the content correctly.
The language of the page should always be set on the HTML tag, but you also need to set the languages of any parts that might be different. For example, you might have a link labelled “Cymraeg“ to switch the language into Welsh. If you don’t add a lang attribute with a Welsh code, the screenreader will try to read it out in English and it will get the pronunciation wrong.
<html lang="en"> ... <nav> <ul> <li><a href="home">Home</a></li> <li><a href="welsh" lang="cy">Cymraeg</a></li> ...
If you don’t set the language of the page, you will fail WCAG 3.1.1 Language of page, and if you don’t tag up any differences in language correctly you will fail WCAG 3.1.2 Language of parts.
If you have repetitive content on a page then you need to provide a way to skip over that content. The most common use of a skip link is to bypass the navigation menu by placing a link at the top of the body tag which jumps to the main tag.
You may also need skip links if you include things like social media feeds which can trap a keyboard user.
<body> <a href="#main-content">Skip to main content</a> <nav> ... </nav> <main id="main-content"> ... </main> </body>
Skip links are often not visible on the page, they are styled to only appear when using screenreaders or when they receive keyboard focus. A skip link does not need to be hidden from the page, but they do need to be present to jump over anything which might be a burden for the user.
If there are any time limits on the service, then they will need to be accessible. The most common timeout encountered on GOV.UK services is the session.
If you have any kind of timeout in your service then it must meet one of the following criteria in order to be considered compliant:
- the default time limit is set to at least 20 hours
- the user must be able to turn off the time limit completely before encountering it
- the user must be able to adjust the time limit before encountering it, to a minimum of 10 times the original time limit
- the user must be warned they are about to reach the time limit and be given at least 20 seconds to reset the timer. The user must be allowed to do reset the timer at least 10 times, and resetting the timer must not clear any of the information the user has already entered.
The only exceptions are when the time limit is in real-time, such as an auction which ends at 5pm. Or, if the time limit is essential such as booking tickets where the tickets can only be placed on hold a reasonable amount of time.
Assistive technologies rely on code being valid. Like a browser, if the code is not valid, then the technology has to try and guess how it should be interpreted, and this can make them behave in an unpredictable way.
Validation and error messages
Validation might be done in the frontend, in the back-end, or both. There are accessibility considerations for any kind of validation.
Real time validation
It is recommended that forms on a page are only validated once the user submits the form. Real-time validation can be annoying and inaccessible. It tends to throw errors before you’ve finished typing which can cause confusion.
On submit validation
If we do in browser validation on submit, we need to make sure that the user is alerted to the error each time they click submit, and they are taken to the relevant error.
When we don’t do this, often secondary form errors are not highlighted to screen reader users, as there is no change of state on the page.
Dealing with user input
If you know what you’re expecting, it can be tempting to lock down the fields. But you should not use limitations like a maxlength attribute. These can cause difficulties for people using voice recognition software such as Dragon.
When using voice recognition software, when the user pauses for breath it can automatically add a space. It is much more accessible to tell the user there is a character limit in the hint text, but don’t actually limit the field. Then you can remove the whitespace and validate what was actually inputted once the form is submitted.
For example, if you were trying to validate a National Insurance number you would use the following steps:
- allow the user to enter more than 9 characters
- allow the user to submit the form
- remove whitespaces, hyphens etc, and convert to uppercase
- check it is a valid National Insurance number
- accept the data as valid or reload the page with errors
This way we aren’t burdening the user with getting everything perfect. We know assistive technologies can add spaces, and we know some people won’t use capital letters, so we can do the hard work to make it simple.
Do not add random database rules
When analysing database schema, it is quite common to find character limits and rules which do not represent real world scenarios. Making assumptions about how long a persons name should be, or not allowing characters with accents or hyphens can quickly make things inaccessible.
Many assistive technologies allow people to create their own dictionaries. These are words or phrases that are common to the user but not to the native language. Their name is one of the things they will most likely store. We should not be telling people they entered their name wrong, and we should not be creating barriers for assistive technology by forcing the user to format their name in a way which fits the rules we’ve made up.
Whenever a validation error is detected, you must inform the user that there is an error, and you must make it clear how to fix the error.
The standard way to do this in Government is to use the following patterns and components in the GOV.UK Design System.
- GOV.UK pattern for validation errors
- GOV.UK Error summary component
- GOV.UK Error messages components
It is not enough to just tell the user there is an error somewhere. You must make it obvious to them which fields are causing the error and clearly explain what they must do to fix it.
Error pages are different to validation errors. These are pages your user might see when something goes wrong with the service on a technical level rather than something the user has entered incorrectly.
These errors are called server errors or HTTP status codes and you must consider what you will show the user if one of them occurs. You should not just relay the code to the user because they will not understand what has gone wrong.
For example, if the user tries to navigate to a step in a journey several days after they’ve submitted an application, do not just show them a page which says “401: Unauthorised” or “Session expired”. Instead, you could explain to the user why they cannot start on this page, or redirect them back to the start page of the journey.