Vize

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

Bad · Good

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.

Implementation · All rules

a11y/no-access-key

Disallow the use of the accesskey attribute

Bad · Good

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.

Implementation · All rules

a11y/no-aria-hidden-on-focusable

Disallow aria-hidden="true" on focusable elements

Bad · Good

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.

Implementation · All rules

a11y/no-autofocus

Disallow the use of the autofocus attribute

Bad · Good

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.

Implementation · All rules

a11y/no-distracting-elements

Disallow distracting elements like <marquee> and <blink>

Bad · Good

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.

Implementation · All rules

a11y/no-i-for-icon

Disallow using <i> element for icons

Bad · Good

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.

Implementation · All rules

a11y/no-redundant-roles

Disallow redundant ARIA roles

Bad · Good

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.

Implementation · All rules

a11y/no-refer-to-non-existent-id

Disallow references to non-existent IDs

Bad · Good

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.

Implementation · All rules