---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Accessibility
Accessibility is important for users who use screen readers or rely on keyboard-only functionality
to ensure they have an equivalent experience to sighted mouse users.
This page contains guidelines we should follow.
## Quick summary
Since [no ARIA is better than bad ARIA](https://www.w3.org/TR/wai-aria-practices/#no_aria_better_bad_aria),
review the following recommendations before using `aria-*`, `role`, and `tabindex`.
Use semantic HTML, which has accessibility semantics baked in, and ideally test with
[relevant combinations of screen readers and browsers](https://www.accessibility-developer-guide.com/knowledge/screen-readers/relevant-combinations/).
In [WebAIM's accessibility analysis of the top million home pages](https://webaim.org/projects/million/#aria),
they found that "ARIA correlated to higher detectable errors".
It is likely that *misuse* of ARIA is a big cause of increased errors,
so when in doubt don't use `aria-*`, `role`, and `tabindex` and stick with semantic HTML.
## Enable keyboard navigation on macOS
By default, macOS limits the tab key to **Text boxes and lists only**. To enable full keyboard navigation:
1. Open **System Preferences**.
1. Select **Keyboard**.
1. Open the **Shortcuts** tab.
1. Enable the setting **Use keyboard navigation to move focus between controls**.
You can read more about enabling browser-specific keyboard navigation on [a11yproject](https://www.a11yproject.com/posts/macos-browser-keyboard-navigation/).
## Quick checklist
- [Text](#text-inputs-with-accessible-names),
[select](#select-inputs-with-accessible-names),
[checkbox](#checkbox-inputs-with-accessible-names),
[radio](#radio-inputs-with-accessible-names),
[file](#file-inputs-with-accessible-names),
and [toggle](#gltoggle-components-with-an-accessible-names) inputs have accessible names.
- [Buttons](#buttons-and-links-with-descriptive-accessible-names),
[links](#buttons-and-links-with-descriptive-accessible-names),
and [images](#images-with-accessible-names) have descriptive accessible names.
- Icons
- [Non-decorative icons](#icons-that-convey-information) have an `aria-label`.
- [Clickable icons](#icons-that-are-clickable) are buttons, that is, `` is used and not ``.
- Icon-only buttons have an `aria-label`.
- Interactive elements can be [accessed with the Tab key](#support-keyboard-only-use) and have a visible focus state.
- Elements with [tooltips](#tooltips) are focusable using the Tab key.
- Are any `role`, `tabindex` or `aria-*` attributes unnecessary?
- Can any `div` or `span` elements be replaced with a more semantic [HTML element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element) like `p`, `button`, or `time`?
## Provide a good document outline
[Headings are the primary mechanism used by screen reader users to navigate content](https://webaim.org/projects/screenreadersurvey8/#finding).
Therefore, the structure of headings on a page should make sense, like a good table of contents.
We should ensure that:
- There is only one `h1` element on the page.
- Heading levels are not skipped.
- Heading levels are nested correctly.
## Provide accessible names for screen readers
To provide markup with accessible names, ensure every:
- `input` has an associated `label`.
- `button` and `a` have child text, or `aria-label` when child text isn't present, such as for an icon button with no content.
- `img` has an `alt` attribute.
- `fieldset` has `legend` as its first child.
- `figure` has `figcaption` as its first child.
- `table` has `caption` as its first child.
Groups of checkboxes and radio inputs should be grouped together in a `fieldset` with a `legend`.
`legend` gives the group of checkboxes and radio inputs a label.
If the `label`, child text, or child element is not visually desired,
use `.gl-sr-only` to hide the element from everything but screen readers.
### Examples of providing accessible names
The following subsections contain examples of markup that render HTML elements with accessible names.
Note that [when using `GlFormGroup`](https://bootstrap-vue.org/docs/components/form-group#accessibility):
- Passing only a `label` prop renders a `fieldset` with a `legend` containing the `label` value.
- Passing both a `label` and a `label-for` prop renders a `label` that points to the form input with the same `label-for` ID.
#### Text inputs with accessible names
When using `GlFormGroup`, the `label` prop alone does not give the input an accessible name.
The `label-for` prop must also be provided to give the input an accessible name.
Text input examples:
```html
```
Textarea examples:
```html
```
Alternatively, you can use a plain `label` element:
```html
```
#### Select inputs with accessible names
Select input examples:
```html
```
#### Checkbox inputs with accessible names
Single checkbox:
```html
{{ __('Task complete') }}
{{ __('Task complete') }}
```
Multiple checkboxes:
```html
{{ __('Task 1') }}{{ __('Task 2') }}{{ __('Task 1') }}{{ __('Task 2') }}
```
#### Radio inputs with accessible names
Single radio input:
```html
{{ __('Opened') }}
{{ __('Opened') }}
```
Multiple radio inputs:
```html
{{ __('Opened') }}{{ __('Closed') }}{{ __('Opened') }}{{ __('Closed') }}
```
#### File inputs with accessible names
File input examples:
```html
```
#### GlToggle components with an accessible names
`GlToggle` examples:
```html
```
#### GlFormCombobox components with an accessible names
`GlFormCombobox` examples:
```html
```
#### Images with accessible names
Image examples:
```html
```
#### Buttons and links with descriptive accessible names
Buttons and links should have accessible names that are descriptive enough to be understood in isolation.
```html
{{ __('Submit') }}{{ __('page') }}{{ __('Submit review') }}{{ __("GitLab's accessibility page") }}
```
#### Links styled like buttons
Links can be styled like buttons using `GlButton`.
```html
{{ __('Link styled as a button') }}
```
## Role
In general, avoid using `role`.
Use semantic HTML elements that implicitly have a `role` instead.
| Bad | Good |
| --- | --- |
| `