Accessibility interactions
Use these rules when reviewing how people interact with a component: keyboard access, focus, mouse handlers, hidden controls, and references to other elements. Check them when introducing custom controls or changing visibility and event handling.
For example, a focusable element hidden from assistive technology is covered by
no-aria-hidden-on-focusable.
Compare its Bad/Good examples, use the shown configuration, then run vp run lint.
The complete accessibility guide explains how these checks fit together.
Every rule on this page includes its purpose, prerequisites, configuration, and complete Bad/Good examples. Highlighted lines show the changes; copied code keeps the complete source. Each packet states its current support limits.
| Rule | Examples | Purpose |
|---|---|---|
a11y/mouse-events-have-key-events |
Bad · Good | Require focus/blur events with mouse events |
a11y/no-access-key |
Bad · Good | Disallow the use of the accesskey attribute |
a11y/no-aria-hidden-on-focusable |
Bad · Good | Disallow aria-hidden="true" on focusable elements |
a11y/no-autofocus |
Bad · Good | Disallow the use of the autofocus attribute |
a11y/no-distracting-elements |
Bad · Good | Disallow distracting elements like <marquee> and <blink> |
a11y/no-i-for-icon |
Bad · Good | Disallow using <i> element for icons |
a11y/no-redundant-roles |
Bad · Good | Disallow redundant ARIA roles |
a11y/no-refer-to-non-existent-id |
Bad · Good | Disallow references to non-existent IDs |
All rules · Rule Options · ESLint migration map · Project checks · Attributes across components
a11y/mouse-events-have-key-events
Require focus/blur events with mouse events
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/mouse-events-have-key-events": "warn"
}
},
},
});
vp run lint
Bad
Preview visibility changes only through mouse enter and leave handlers.
<template>
<div @mouseenter="showPreview" @mouseleave="hidePreview">Preview</div>
</template>
Good
The same preview actions run on focus and blur, and the button can receive keyboard focus.
<template>
<button
type="button"
@focus="showPreview"
@blur="hidePreview"
@mouseenter="showPreview"
@mouseleave="hidePreview"
>
Preview
</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-access-key
Disallow the use of the accesskey attribute
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-access-key": "warn"
}
},
},
});
vp run lint
Bad
The accesskey="s" shortcut may conflict with browser or assistive-technology shortcuts.
<template>
<button accesskey="s">Save</button>
</template>
Good
Removing accesskey keeps the ordinary Save button available.
<template>
<button>Save</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-aria-hidden-on-focusable
Disallow aria-hidden="true" on focusable elements
Default severity: error
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-aria-hidden-on-focusable": "error"
}
},
},
});
vp run lint
Bad
The focusable Close button is hidden from the accessibility tree with aria-hidden="true".
<template>
<button aria-hidden="true" @click="close">Close</button>
</template>
Good
The button remains exposed and receives a Close label instead of being hidden.
<template>
<button aria-label="Close" @click="close">Close</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-autofocus
Disallow the use of the autofocus attribute
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-autofocus": "warn"
}
},
},
});
vp run lint
Bad
The input requests automatic focus when it appears.
<template>
<input autofocus name="query" />
</template>
Good
Removing autofocus avoids this automatic focus request while retaining the query input.
<template>
<input name="query" />
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-distracting-elements
Disallow distracting elements like <marquee> and <blink>
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-distracting-elements": "warn"
}
},
},
});
vp run lint
Bad
The marquee element introduces automatically moving text.
<template>
<marquee>Limited offer</marquee>
</template>
Good
A paragraph displays the same offer without the distracting marquee element.
<template>
<p>Limited offer</p>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-i-for-icon
Disallow using <i> element for icons
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-i-for-icon": "warn"
}
},
},
});
vp run lint
Bad
The icon is rendered through i, whose text semantics do not describe an icon-only action.
<template>
<button>
<i class="material-icons">delete</i>
</button>
</template>
Good
A decorative span hides the icon glyph, while the separate Delete item text names the button action.
<template>
<button>
<span class="material-icons" aria-hidden="true">delete</span>
<span class="sr-only">Delete item</span>
</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-redundant-roles
Disallow redundant ARIA roles
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-redundant-roles": "warn"
}
},
},
});
vp run lint
Bad
The native button already has the button role, so role="button" repeats its implicit semantics.
<template>
<button role="button">Save</button>
</template>
Good
Removing the repeated role keeps the button semantics supplied by HTML.
<template>
<button>Save</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
a11y/no-refer-to-non-existent-id
Disallow references to non-existent IDs
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"a11y/no-refer-to-non-existent-id": "warn"
}
},
},
});
vp run lint
Bad
aria-labelledby points to save-label, but no element declares that ID.
<template>
<button aria-labelledby="save-label">Save</button>
</template>
Good
Adding the matching span resolves the reference and provides the button label.
<template>
<span id="save-label">Save changes</span>
<button aria-labelledby="save-label">Save</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.