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.
svelte/packages/svelte/messages/compile-warnings/a11y.md

18 KiB

a11y_accesskey

Avoid using accesskey

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.

<!-- A11y: Avoid using accesskey -->
<div accesskey="z"></div>

a11y_aria_activedescendant_has_tabindex

An element with an aria-activedescendant attribute should have a tabindex value

An element with aria-activedescendant must be tabbable, so it must either have an inherent tabindex or declare tabindex as an attribute.

<!-- A11y: Elements with attribute aria-activedescendant should have tabindex value -->
<div aria-activedescendant="some-id"></div>

a11y_aria_attributes

<%name%> should not have aria-* attributes

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.

<!-- A11y: <meta> should not have aria-* attributes -->
<meta aria-hidden="false" />

a11y_autocomplete_valid

'%value%' is an invalid value for 'autocomplete' on <input type="%type%">

a11y_autofocus

Avoid using autofocus

Enforce that autofocus is not used on elements. Autofocusing elements can cause usability issues for sighted and non-sighted users alike.

<!-- A11y: Avoid using autofocus -->
<input autofocus />

a11y_click_events_have_key_events

Visible, non-interactive elements with a click event must be accompanied by a keyboard event handler. Consider whether an interactive element such as <button type="button"> or <a> might be more appropriate

Enforce that visible, non-interactive elements with an onclick event are accompanied by a keyboard event handler.

Users should first consider whether an interactive element might be more appropriate such as a <button type="button"> element for actions or <a> element for navigations. These elements are more semantically meaningful and will have built-in key handling. E.g. Space and Enter will trigger a <button> and Enter will trigger an <a> element.

If a non-interactive element is required then onclick should be accompanied by an onkeyup or onkeydown handler that enables the user to perform equivalent actions via the keyboard. In order for the user to be able to trigger a key press, the element will also need to be focusable by adding a tabindex. While an onkeypress handler will also silence this warning, it should be noted that the keypress event is deprecated.

<!-- A11y: visible, non-interactive elements with an onclick event must be accompanied by a keyboard event handler. -->
<div onclick={() => {}}></div>

Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.

a11y_consider_explicit_label

Buttons and links should either contain text or have an aria-label or aria-labelledby attribute

a11y_distracting_elements

Avoid <%name%> elements

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>.

<!-- A11y: Avoid <marquee> elements -->
<marquee></marquee>

a11y_figcaption_index

<figcaption> must be first or last child of <figure>

a11y_figcaption_parent

<figcaption> must be an immediate child of <figure>

Enforce that certain DOM elements have the correct structure.

<!-- A11y: <figcaption> must be an immediate child of <figure> -->
<div>
	<figcaption>Image caption</figcaption>
</div>

a11y_hidden

<%name%> element should not be hidden

Certain DOM elements are useful for screen reader navigation and should not be hidden.

<!-- A11y: <h2> element should not be hidden -->
<h2 aria-hidden="true">invisible header</h2>

a11y_img_redundant_alt

Screenreaders already announce <img> elements as an image

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.

<img src="foo" alt="Foo eating a sandwich." />

<!-- aria-hidden, won't be announced by screen reader -->
<img src="bar" aria-hidden="true" alt="Picture of me taking a photo of an image" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Photo of foo being weird." />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="bar" alt="Image of me at a bar!" />

<!-- A11y: Screen readers already announce <img> elements as an image. -->
<img src="foo" alt="Picture of baz fixing a bug." />

a11y_incorrect_aria_attribute_type

The value of '%attribute%' must be a %type%

Enforce that only the correct type of value is used for aria attributes. For example, aria-hidden should only receive a boolean.

<!-- A11y: The value of 'aria-hidden' must be exactly one of true or false -->
<div aria-hidden="yes"></div>

a11y_incorrect_aria_attribute_type_boolean

The value of '%attribute%' must be either 'true' or 'false'. It cannot be empty

a11y_incorrect_aria_attribute_type_id

The value of '%attribute%' must be a string that represents a DOM element ID

a11y_incorrect_aria_attribute_type_idlist

The value of '%attribute%' must be a space-separated list of strings that represent DOM element IDs

a11y_incorrect_aria_attribute_type_integer

The value of '%attribute%' must be an integer

a11y_incorrect_aria_attribute_type_token

The value of '%attribute%' must be exactly one of %values%

a11y_incorrect_aria_attribute_type_tokenlist

The value of '%attribute%' must be a space-separated list of one or more of %values%

a11y_incorrect_aria_attribute_type_tristate

The value of '%attribute%' must be exactly one of true, false, or mixed

a11y_interactive_supports_focus

Elements with the '%role%' interactive role must have a tabindex value

Enforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.

<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->
<div role="button" onkeypress={() => {}} />

a11y_invalid_attribute

'%href_value%' is not a valid %href_attribute% attribute

Enforce that attributes important for accessibility have a valid value. For example, href should not be empty, '#', or javascript:.

Why this matters for accessibility:

  • Screen readers announce links to users, but href="#" provides no meaningful destination information
  • Users who navigate by links (a common screen reader navigation method) will encounter unhelpful link descriptions
  • href="#" scrolls to the top of the page when clicked, which can be disorienting
  • Opening in a new tab results in the same page or a blank page
  • These links cannot be bookmarked or shared

Common mistakes and their solutions:

<!-- ❌ A11y: '' is not a valid href attribute -->
<a href="">Click me</a>

<!-- ❌ A11y: '#' is not a valid href attribute -->
<a href="#">Click me</a>

<!-- ❌ A11y: 'javascript:void(0)' is not a valid href attribute -->
<a href="javascript:void(0)">Click me</a>

Better alternatives:

If you need an element that performs an action (not navigation), use a button:

<!-- ✅ Correct: Use button for actions -->
<button type="button" on:click={handleClick}>Click me</button>

If you need a link that looks like a button, style the button appropriately:

<!-- ✅ Style a button to look like a link if needed -->
<button type="button" class="link-style" on:click={handleClick}>
  Click me
</button>

<style>
  .link-style {
    background: none;
    border: none;
    color: blue;
    text-decoration: underline;
    cursor: pointer;
    padding: 0;
    font: inherit;
  }
</style>

For actual navigation, provide a valid href:

<!-- ✅ Correct: Provide meaningful href for navigation -->
<a href="/page">Go to page</a>
<a href="#section">Go to section</a>

If you're creating a placeholder link during development:

<!-- ✅ Better: Make it clear this is temporary -->
<a href="/todo" aria-label="Link to be implemented">Coming soon</a>

a11y_label_has_associated_control

A form label must be associated with a control

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.
  • Adding for to a label and assigning it the ID of an input on the page.
<label for="id">B</label>

<label>C <input type="text" /></label>

<!-- A11y: A form label must be associated with a control. -->
<label>A</label>

a11y_media_has_caption

<video> elements must have a <track kind="captions">

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.

<video><track kind="captions" /></video>

<audio muted></audio>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video></video>

<!-- A11y: Media elements must have a <track kind=\"captions\"> -->
<video><track /></video>

a11y_misplaced_role

<%name%> should not have role attribute

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.

<!-- A11y: <meta> should not have role attribute -->
<meta role="tooltip" />

a11y_misplaced_scope

The scope attribute should only be used with <th> elements

The scope attribute should only be used on <th> elements.

<!-- A11y: The scope attribute should only be used with <th> elements -->
<div scope="row" />

a11y_missing_attribute

<%name%> element should have %article% %sequence% attribute

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)
  • <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
<!-- A11y: <input type=\"image\"> element should have an alt, aria-label or aria-labelledby attribute -->
<input type="image" />

<!-- A11y: <html> element should have a lang attribute -->
<html></html>

<!-- A11y: <a> element should have an href attribute -->
<a>text</a>

a11y_missing_content

<%name%> element should contain text

Enforce that heading elements (h1, h2, etc.) and anchors have content and that the content is accessible to screen readers

<!-- A11y: <a> element should have child content -->
<a href="/foo"></a>

<!-- A11y: <h1> element should have child content -->
<h1></h1>

a11y_mouse_events_have_key_events

'%event%' event must be accompanied by '%accompanied_by%' event

Enforce that onmouseover and onmouseout are accompanied by onfocus and onblur, respectively. This helps to ensure that any functionality triggered by these mouse events is also accessible to keyboard users.

<!-- A11y: onmouseover must be accompanied by onfocus -->
<div onmouseover={handleMouseover} />

<!-- A11y: onmouseout must be accompanied by onblur -->
<div onmouseout={handleMouseout} />

a11y_no_abstract_role

Abstract role '%role%' is forbidden

a11y_no_interactive_element_to_noninteractive_role

<%element%> cannot have role '%role%'

WAI-ARIA 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.

<!-- A11y: <textarea> cannot have role 'listitem' -->
<textarea role="listitem"></textarea>

a11y_no_noninteractive_element_interactions

Non-interactive element <%element%> should not be assigned mouse or keyboard event listeners

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 include article, banner, complementary, img, listitem, main, region and tooltip.

<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->
<li onclick={() => {}}></li>

<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->
<div role="listitem" onclick={() => {}}></div>

a11y_no_noninteractive_element_to_interactive_role

Non-interactive element <%element%> cannot have interactive role '%role%'

WAI-ARIA 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.

<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
<h3 role="searchbox">Button</h3>

a11y_no_noninteractive_tabindex

noninteractive element cannot have nonnegative tabIndex value

Tab key navigation should be limited to elements on the page that can be interacted with.

<!-- A11y: noninteractive element cannot have nonnegative tabIndex value -->
<div tabindex="0"></div>

a11y_no_redundant_roles

Redundant role '%role%'

Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser has no effect and is redundant.

<!-- A11y: Redundant role 'button' -->
<button role="button">...</button>

<!-- A11y: Redundant role 'img' -->
<img role="img" src="foo.jpg" />

a11y_no_static_element_interactions

<%element%> with a %handler% handler must have an ARIA role

Elements like <div> with interactive handlers like click must have an ARIA role.

<!-- A11y: <div> with click handler must have an ARIA role -->
<div onclick={() => ''}></div>

a11y_positive_tabindex

Avoid tabindex values above zero

Avoid positive tabindex property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.

<!-- A11y: avoid tabindex values above zero -->
<div tabindex="1"></div>

a11y_role_has_required_aria_props

Elements with the ARIA role "%role%" must have the following attributes defined: %props%

Elements with ARIA roles must have all required attributes for that role.

<!-- A11y: A11y: Elements with the ARIA role "checkbox" must have the following attributes defined: "aria-checked" -->
<span role="checkbox" aria-labelledby="foo" tabindex="0"></span>

a11y_role_supports_aria_props

The attribute '%attribute%' is not supported by the role '%role%'

Elements with explicit or implicit roles defined contain only aria-* properties supported by that role.

<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>

a11y_role_supports_aria_props_implicit

The attribute '%attribute%' is not supported by the role '%role%'. This role is implicit on the element <%name%>

Elements with explicit or implicit roles defined contain only aria-* properties supported by that role.

<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<div role="link" aria-multiline></div>

<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<li aria-required></li>

a11y_unknown_aria_attribute

Unknown aria attribute 'aria-%attribute%'

Unknown aria attribute 'aria-%attribute%'. Did you mean '%suggestion%'?

Enforce that only known ARIA attributes are used. This is based on the WAI-ARIA States and Properties spec.

<!-- A11y: Unknown aria attribute 'aria-labeledby' (did you mean 'labelledby'?) -->
<input type="image" aria-labeledby="foo" />

a11y_unknown_role

Unknown role '%role%'

Unknown role '%role%'. Did you mean '%suggestion%'?

Elements with ARIA roles must use a valid, non-abstract ARIA role. A reference to role definitions can be found at WAI-ARIA site.

<!-- A11y: Unknown role 'toooltip' (did you mean 'tooltip'?) -->
<div role="toooltip"></div>