--- 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/product/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://w3c.github.io/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`](#examples-of-providing-accessible-names). - button and link have [visible text](#buttons-and-links-with-descriptive-accessible-names), or `aria-label` when there is no visible text, such as for an icon button with no content. - image has an [`alt` attribute](#images-with-accessible-names). - `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 | | --- | --- | | `
` | `