Accessibility
The Design Standards has accessibility built in as a key feature. This page outlines some general best practice guidelines to think about when creating digital services.
Accessible Rich Internet Applications (ARIA)
ARIA provides a set of attributes that add additional information to HTML elements. The aim was to provide developers ways to make non-native widgets more accessible. Since ARIA was created and adopted there are more native HTML elements that reduce the necessity of ARIA.
ARIA will not automatically make your HTML more accessible. Poorly used ARIA may add nothing or, worse, lead to more confusing interactions for people. Try to use native elements where possible.
Where this is not possible, consult the ARIA Authoring Practices to ensure you are using ARIA in line with best practice.
The ARIA specification is divided into categories of attributes, one of which is roles, and the other being states & properties.
WAI-ARIA Roles
ARIA roles provide semantic meaning to content, allowing screen readers and other tools to present and support interaction with an object in a way that is consistent with user expectations of that type of object. ARIA roles can be used to describe elements that don't natively exist in HTML or exist but don't yet have full browser support.
Document structure roles
Document structure roles are used to provide a structural description for a section of content. Most of these roles should no longer be used as browsers now support semantic HTML element with the same meaning. The roles without HTML equivalents, such as presentation, toolbar and tooltip roles, provide information on the document structure to assistive technologies such as screen readers as equivalent native HTML tags are not available.
| Attribute | What it does |
|---|---|
toolbar |
Collection of commonly used controls, such as buttons or checkboxes, grouped together in a compact visual form. Only use the toolbar role to group 3 or more controls. |
tooltip |
Provides contextual information about an element when that owning element receives focus or is hovered over, but is otherwise not visible on the page. |
feed |
A dynamic scrollable list of articles in which articles are added to or removed from either end of the list as the user scrolls. A feed enables screen readers to use the browse mode reading cursor to both read and scroll through a stream of rich content that may continue scrolling infinitely by loading more content as the user reads. |
math |
Indicates that the content represents a mathematical expression. If the math element has only presentational children and the accessible name is intended to convey the mathematical expression, use aria-label to provide a string that represents the expression. If the math element contains navigable content that conveys the mathematical expression and a visible label for the expression is present, use aria-labelledby. Otherwise, use aria-label to name the expression, e.g., aria-label="Pythagorean Theorem". |
presentation / none |
The presentation role and its synonym none remove an element's implicit ARIA semantics from being exposed to the accessibility tree. While ARIA is primarily used to express semantics, there are some situations where hiding an element's semantics from assistive technologies is helpful. This is done with the presentation role or its synonym role none, which declare that an element is being used only for presentation and therefore does not have any accessibility semantics. |
note |
Can be added to parenthetic or ancillary content if no other native element or other role fits the purpose. Naming a note is optional, but can help screen reader users understand its context and purpose. The name can be provided using aria-labelledby if a visible label is present, otherwise with aria-label. |
For most document structure roles, semantic HTML equivalent elements are available and supported. Find out more information on ARIA roles.
States & properties
| Attribute | State or property | Value | What it does |
|---|---|---|---|
aria-activedescendant |
property | ID of another element | Identifies the currently active element when focus is on a composite widget, combobox, textbox, group, or application. The attribute manages providing assistive technologies with information as to which element has focus, but doesn't actually create focus. |
aria-atomic |
property | true/false | Shows if all or just parts of the changed region will be presented by assistive technologies (e.g. screen readers) based on change notifications defined by the "aria-relevant" attribute. Related: aria-relevant |
aria-autocomplete |
property | inline/list/both/none | Shows if an autocomplete feature is provided and what type of autocomplete it is |
aria-busy |
state | true/false | Shows if an element and its subtree are in the process of being updated |
aria-checked |
state | true/false/mixed | Shows the current "checked" state of checkboxes, radio buttons etc. Related aria-pressed and aria-selected |
aria-controls |
property | ID(s) of one or more elements | Identifies the element(s) which are controlled by the current element. Related aria-owns |
aria-describedby |
property | ID(s) of one or more elements | Identifies the element(s) that describes the object. Related aria-labelledby |
aria-disabled |
state | true/false | Shows whether an element is disabled. Related aria-hidden and aria-read-only |
aria-dropeffect |
property | copy/move/link/execute/popup/none | Shows which actions can be taken when a dragged object is released on a drop target. Assistive technologies can then tell the user what options are available to them |
aria-expanded |
state | true/false/undefined | Shows if an element/grouping element it controls is expanded or collapsed |
aria-flowto |
property | ID(s) of one or more elements | Shows the next element(s) in an alternate reading order of content. This lets assistive technologies over-ride the general default of reading in document source order, if the user specifies |
aria-grabbed |
state | true/false/undefined | Shows if an element is "grabbed" during drag and drop |
aria-haspopup |
property | true/false | Shows if an element has a popup context/sub-level menu |
aria-hidden |
state | true/false | Shows if an element (and all of its descendants) are not visible/perceivable to any user as implemented by the author. Related aria-disabled |
aria-invalid |
state | grammer/false/spelling/true | Shows that the value that has been entered does not match the expected/required format |
aria-label |
property | no restriction | Used to give a label to an element when there is no visible label on the screen. Related aria-labelledby |
aria-labelledby |
property | ID(s) of one or more elements | Shows which element(s) labels the current element. Related aria-label and aria-describedby |
aria-level |
property | any whole number | Shows an element's hierarchical level within a structure |
aria-multiline |
property | true/false | Shows if a text box will accept more than one line of text |
aria-multiselectable |
property | true/false | Shows if the user can select multiple items from the selectable descendants |
aria-orientation |
property | vertical/horizontal | Describes whether the orientation of an element is horizontal or vertical |
aria-owns |
property | ID(s) of one or more elements | Identifies element(s) in order to define the parent/child relationship between DOM elements where the DOM hierarchy cannot be used to represent the relationship. Related aria-controls |
aria-posinset |
property | any whole number | Shows the number/position of an element in the current set of list/tree items. Not needed if all the elements in the set are present in the DOM. Related aria-setsize |
aria-pressed |
state | true/false/mixed/undefined | Shows what a toggle button's current "pressed" state is. Related aria-checked and aria-selected |
aria-readonly |
property | true/false | Shows an element is operable but cannot be edited. Related aria-disabled |
aria-relevant |
property | additions/removals/text/all/additions text | Shows which user agent change notifications (e.g. additions, removals) assistive technologies will receive within a live region. Related aria-atomic |
aria-required |
property | true/false | Used on a "required" form field to show that a user must enter some data into the element in order to sub,it the form |
aria-selected |
state | true/false/undefinied | Shows what various widgets' current "selected" state is. Related aria-checked and aria-pressed |
aria-setsize |
property | any whole number | Shows how many items there are in the current set of list/tree items. Not needed if all elements in the set are present in the DOM. Related aria-posinset |
aria-sort |
property | ascending/descending/none/other | Shows how items in a table/grid are sorted |
aria-valuemax |
property | any whole number | Shows the maximum allowed value for a range widget |
aria-valuemin |
property | any whole number | Shows the minimum allowed value for a range widget |
aria-valuenow |
property | any whole number | Shows the current value for a range widget. Related aria-valuetext |
aria-valuetext |
property | no restriction | Shows the text alternative (human readable) of the attribute "aria-valuenow" for a range widget |
Keyboard interaction
For keyboard users, such as people who use a screen reader, it is essential that all content can be interacted without using a mouse. For elements such as links, buttons and native form elements the browser and operating system ensures this functionality. Widgets that have no native element, such as an accordion or widget, require developers to ensure that they can be used with a keyboard.
Styling for keyboard focus
For sighted keyboard only users it is important that the interactive element that they are focussed on is clearly identified. This includes links, buttons and form fields. Relying on the browser to do this is usually not sufficient since some browser default options for focus styling is too subtle.
Focus styling can easily be included using the CSS pseudo selector :focus. It may be sufficient to use the same styling for :hover. However, it is better to have something more visually noticeable for focus styling. For example sepa.scot uses:
a:focus {
background-color: var(--verdant-green);
color: #000;
text-decoration: none;
}
Colour contrast
For some people poor contrast between the foreground colour of text and its background can make the text extremely difficult or impossible to read. This applies to text on images, gradients, buttons and other elements.
Ensure that the colours used in your palette are selected so that they offer a good contrast. Colours can be checked using tools such as WebAIM contrast checker. This tool can also offer alternatives close to your selected colours.
Alternative text
All images must have alternative text provided that describes the information or function of the image.
A simple trick to help deciding on alternative text is to imagine you are reading the page to someone over the phone. What would you say to them about the image?
- Is it a graph showing a clear trend?
- Does it convey an idea that supports the text content?
- Is it a person?
- Are they doing something important?
- Or is the image simply for decoration and doesn’t add anything to the meaning of the page?
The Web Accessibility Tutorials from W3C includes a useful alt decision tree that can help you decide what alternative text you need to include.
Heading structure
Headings communicate the organisation of a page and are extremely useful in helping people navigate pages. Headings are ranked from <h1>, the most important, to <h6> the least. Avoid skipping headings, for example having an <h4> following an <h2>. People who rely on the ranking to help them understand the content can be confused with skips like this.
The heading conveys meaning about the content so avoid using headings just for their style. Conversely, if something is styled to look like a heading then it should be marked up as a heading to convey that meaning in code.
Visually hiding content
There are sometimes instances where screen reader users need content but sighted users do not. In each instance it is worth thinking if this really is the case: if the content is important enough for some users, why not others?
When hiding content that you want screen reader users to still be able to accesss never use display: none or visibility: hidden. These will remove the content from all ‘displays’ including screen reader ‘displays’. Similarly giving an element a height or width of 0 will remove it from the content flow and most screen readers will ignore it.
The following CSS is an accessible method of hiding content visually, and it is what the Design Standard uses.
.sr-only, .visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}