mirror of https://github.com/sveltejs/svelte
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
330 lines
12 KiB
330 lines
12 KiB
3 years ago
|
---
|
||
2 years ago
|
title: 'Accessibility warnings'
|
||
3 years ago
|
---
|
||
|
|
||
3 years ago
|
Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you at compile time if you write inaccessible markup. However, keep in mind that many accessibility issues can only be identified at runtime using other automated tools and by manually testing your application.
|
||
3 years ago
|
|
||
3 years ago
|
Here is a list of accessibility checks Svelte will do for you.
|
||
3 years ago
|
|
||
2 years ago
|
## `a11y-accesskey`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce no `accesskey` on element. Access keys are HTML attributes that allow web developers to assign keyboard shortcuts to elements. Inconsistencies between keyboard shortcuts and keyboard commands used by screen reader and keyboard-only users create accessibility complications. To avoid complications, access keys should not be used.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: Avoid using accesskey --><div accessKey="z" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-aria-activedescendant-has-tabindex`
|
||
2 years ago
|
|
||
|
An element with `aria-activedescendant` must be tabbable, so it must either have an inherent `tabindex` or declare `tabindex` as an attribute.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->
|
||
|
<div aria-activedescendant="some-id" />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-aria-attributes`
|
||
3 years ago
|
|
||
|
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `aria-*` props.
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: <meta> should not have aria-* attributes -->
|
||
2 years ago
|
<meta aria-hidden="false" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-autofocus`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce that `autofocus` is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: Avoid using autofocus -->
|
||
2 years ago
|
<input autofocus />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-click-events-have-key-events`
|
||
2 years ago
|
|
||
2 years ago
|
Enforce `on:click` is accompanied by at least one of the following: `on:keyup`, `on:keydown`, `on:keypress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.
|
||
2 years ago
|
|
||
|
This does not apply for interactive or hidden elements.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event. -->
|
||
|
<div on:click={() => {}} />
|
||
|
```
|
||
|
|
||
2 years ago
|
Note that the `keypress` event is now deprecated, so it is officially recommended to use either the `keyup` or `keydown` event instead, accordingly.
|
||
|
|
||
2 years ago
|
## `a11y-distracting-elements`
|
||
3 years ago
|
|
||
|
Enforces that no distracting elements are used. Elements that can be visually distracting can cause accessibility issues with visually impaired users. Such elements are most likely deprecated, and should be avoided.
|
||
|
|
||
|
The following elements are visually distracting: `<marquee>` and `<blink>`.
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: Avoid <marquee> elements -->
|
||
|
<marquee />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-hidden`
|
||
3 years ago
|
|
||
3 years ago
|
Certain DOM elements are useful for screen reader navigation and should not be hidden.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: <h2> element should not be hidden --><h2 aria-hidden="true">invisible header</h2>
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-img-redundant-alt`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce img alt attribute does not contain the word image, picture, or photo. Screen readers already announce `img` elements as an image. There is no need to use words such as _image_, _photo_, and/or _picture_.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<img src="foo" alt="Foo eating a sandwich." />
|
||
|
|
||
|
<!-- aria-hidden, won't be announced by screen reader -->
|
||
3 years ago
|
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />
|
||
3 years ago
|
|
||
3 years ago
|
<!-- A11y: Screen readers already announce <img> elements as an image. -->
|
||
3 years ago
|
<img src="foo" alt="Photo of foo being weird." />
|
||
|
|
||
3 years ago
|
<!-- A11y: Screen readers already announce <img> elements as an image. -->
|
||
3 years ago
|
<img src="bar" alt="Image of me at a bar!" />
|
||
|
|
||
3 years ago
|
<!-- A11y: Screen readers already announce <img> elements as an image. -->
|
||
3 years ago
|
<img src="foo" alt="Picture of baz fixing a bug." />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-incorrect-aria-attribute-type`
|
||
2 years ago
|
|
||
|
Enforce that only the correct type of value is used for aria attributes. For example, `aria-hidden`
|
||
|
should only receive a boolean.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
|
||
2 years ago
|
<div aria-hidden="yes" />
|
||
2 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-invalid-attribute`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce that attributes important for accessibility have a valid value. For example, `href` should not be empty, `'#'`, or `javascript:`.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: '' is not a valid href attribute -->
|
||
2 years ago
|
<a href="">invalid</a>
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-interactive-supports-focus`
|
||
2 years ago
|
|
||
|
Enforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->
|
||
|
<div role="button" on:keypress={() => {}} />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-label-has-associated-control`
|
||
3 years ago
|
|
||
|
Enforce that a label tag has a text label and an associated control.
|
||
|
|
||
|
There are two supported ways to associate a label with a control:
|
||
|
|
||
|
- Wrapping a control in a label tag.
|
||
3 years ago
|
- Adding `for` to a label and assigning it the ID of an input on the page.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<label for="id">B</label>
|
||
|
|
||
|
<label>C <input type="text" /></label>
|
||
|
|
||
|
<!-- A11y: A form label must be associated with a control. -->
|
||
|
<label>A</label>
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-media-has-caption`
|
||
3 years ago
|
|
||
|
Providing captions for media is essential for deaf users to follow along. Captions should be a transcription or translation of the dialogue, sound effects, relevant musical cues, and other relevant audio information. Not only is this important for accessibility, but can also be useful for all users in the case that the media is unavailable (similar to `alt` text on an image when an image is unable to load).
|
||
|
|
||
|
The captions should contain all important and relevant information to understand the corresponding media. This may mean that the captions are not a 1:1 mapping of the dialogue in the media content. However, captions are not necessary for video components with the `muted` attribute.
|
||
|
|
||
2 years ago
|
```svelte
|
||
|
<video><track kind="captions" /></video>
|
||
3 years ago
|
|
||
2 years ago
|
<audio muted />
|
||
3 years ago
|
|
||
|
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
|
||
2 years ago
|
<video />
|
||
3 years ago
|
|
||
|
<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
|
||
|
<video><track /></video>
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-misplaced-role`
|
||
3 years ago
|
|
||
|
Certain reserved DOM elements do not support ARIA roles, states and properties. This is often because they are not visible, for example `meta`, `html`, `script`, `style`. This rule enforces that these DOM elements do not contain the `role` props.
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: <meta> should not have role attribute -->
|
||
2 years ago
|
<meta role="tooltip" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-misplaced-scope`
|
||
3 years ago
|
|
||
3 years ago
|
The scope attribute should only be used on `<th>` elements.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: The scope attribute should only be used with <th> elements --><div scope="row" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-missing-attribute`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce that attributes required for accessibility are present on an element. This includes the following checks:
|
||
|
|
||
|
- `<a>` should have an href (unless it's a [fragment-defining tag](https://github.com/sveltejs/svelte/issues/4697))
|
||
|
- `<area>` should have alt, aria-label, or aria-labelledby
|
||
|
- `<html>` should have lang
|
||
|
- `<iframe>` should have title
|
||
|
- `<img>` should have alt
|
||
|
- `<object>` should have title, aria-label, or aria-labelledby
|
||
|
- `<input type="image">` should have alt, aria-label, or aria-labelledby
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
|
||
2 years ago
|
<input type="image" />
|
||
3 years ago
|
|
||
|
<!-- A11y: <html> element should have a lang attribute -->
|
||
2 years ago
|
<html />
|
||
3 years ago
|
|
||
|
<!-- A11y: <a> element should have an href attribute -->
|
||
|
<a>text</a>
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-missing-content`
|
||
3 years ago
|
|
||
|
Enforce that heading elements (`h1`, `h2`, etc.) and anchors have content and that the content is accessible to screen readers
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: <a> element should have child content -->
|
||
2 years ago
|
<a href="/foo" />
|
||
3 years ago
|
|
||
|
<!-- A11y: <h1> element should have child content -->
|
||
2 years ago
|
<h1 />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-mouse-events-have-key-events`
|
||
3 years ago
|
|
||
|
Enforce that `on:mouseover` and `on:mouseout` are accompanied by `on:focus` and `on:blur`, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: on:mouseover must be accompanied by on:focus -->
|
||
|
<div on:mouseover={handleMouseover} />
|
||
|
|
||
|
<!-- A11y: on:mouseout must be accompanied by on:blur -->
|
||
|
<div on:mouseout={handleMouseout} />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-no-redundant-roles`
|
||
3 years ago
|
|
||
|
Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser [has no effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.
|
||
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: Redundant role 'button' -->
|
||
|
<button role="button" />
|
||
|
|
||
|
<!-- A11y: Redundant role 'img' -->
|
||
|
<img role="img" src="foo.jpg" />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-no-interactive-element-to-noninteractive-role`
|
||
2 years ago
|
|
||
|
[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert an interactive element to a non-interactive element. Non-interactive ARIA roles include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: <textarea> cannot have role 'listitem' -->
|
||
|
<textarea role="listitem" />
|
||
|
```
|
||
|
|
||
2 years ago
|
### `a11y-no-noninteractive-element-interactions`
|
||
|
|
||
|
A non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<p>`, `<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
|
||
|
|
||
|
```sv
|
||
|
<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->
|
||
|
<li on:click={() => {}} />
|
||
|
|
||
|
<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->
|
||
|
<div role="listitem" on:click={() => {}} />
|
||
|
```
|
||
|
|
||
2 years ago
|
### `a11y-no-noninteractive-element-to-interactive-role`
|
||
|
|
||
|
[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
|
||
|
<h3 role="searchbox">Button</h3>
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-no-noninteractive-tabindex`
|
||
2 years ago
|
|
||
|
Tab key navigation should be limited to elements on the page that can be interacted with.
|
||
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: noninteractive element cannot have nonnegative tabIndex value --><div tabindex="0" />
|
||
2 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-positive-tabindex`
|
||
3 years ago
|
|
||
3 years ago
|
Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: avoid tabindex values above zero --><div tabindex="1" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-role-has-required-aria-props`
|
||
2 years ago
|
|
||
|
Elements with ARIA roles must have all required attributes for that role.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following attributes defined: "aria-checked" -->
|
||
2 years ago
|
<span role="checkbox" aria-labelledby="foo" tabindex="0" />
|
||
2 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-role-supports-aria-props`
|
||
2 years ago
|
|
||
|
Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.
|
||
|
|
||
2 years ago
|
```svelte
|
||
2 years ago
|
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
|
||
|
<div role="link" aria-multiline />
|
||
|
|
||
|
<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
|
||
|
<li aria-required />
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-structure`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce that certain DOM elements have the correct structure.
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: <figcaption> must be an immediate child of <figure> -->
|
||
|
<div>
|
||
|
<figcaption>Image caption</figcaption>
|
||
|
</div>
|
||
|
```
|
||
|
|
||
2 years ago
|
## `a11y-unknown-aria-attribute`
|
||
3 years ago
|
|
||
3 years ago
|
Enforce that only known ARIA attributes are used. This is based on the [WAI-ARIA States and Properties spec](https://www.w3.org/WAI/PF/aria-1.1/states_and_properties).
|
||
3 years ago
|
|
||
2 years ago
|
```svelte
|
||
3 years ago
|
<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
|
||
2 years ago
|
<input type="image" aria-labeledby="foo" />
|
||
3 years ago
|
```
|
||
|
|
||
2 years ago
|
## `a11y-unknown-role`
|
||
3 years ago
|
|
||
|
Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at [WAI-ARIA](https://www.w3.org/TR/wai-aria/#role_definitions) site.
|
||
|
|
||
2 years ago
|
```svelte
|
||
|
<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) --><div role="toooltip" />
|
||
3 years ago
|
```
|