Vize

アクセシビリティのルール

このページに、各ルールの目的・前提・設定と、省略のない悪い例・良い例をまとめています。変更箇所は行の色で示します。コードをコピーすると、ソースコード全体を取得できます。各例に現在の対応範囲も明記しています。

ルール 例 目的
a11y/alt-text 悪い · 良い 画像などのメディアに代替テキストを用意します。
a11y/anchor-has-content 悪い · 良い リンクに支援技術で読める内容を用意します。
a11y/anchor-is-valid 悪い · 良い リンクの href に有効な移動先を指定します。
a11y/aria-props 悪い · 良い 存在しない ARIA 属性を検出します。
a11y/aria-role 悪い · 良い 抽象ロールを除く、有効な ARIA role を指定します。
a11y/aria-unsupported-elements 悪い · 良い ARIA 属性を使用できない要素への指定を検出します。
a11y/click-events-have-key-events 悪い · 良い クリックで操作する要素にキーボード操作も用意します。
a11y/form-control-has-label 悪い · 良い フォーム部品に関連付けられたラベルを用意します。
a11y/heading-has-content 悪い · 良い 見出しに支援技術で読める内容を用意します。
a11y/heading-levels 悪い · 良い 見出しの階層を飛ばした指定を検出します。
a11y/iframe-has-title 悪い · 良い iframe に内容を説明する title を指定します。
a11y/img-alt 悪い · 良い 画像に alt 属性を指定します。装飾画像は空の alt を使います。
a11y/interactive-supports-focus 悪い · 良い 操作可能な role の要素をフォーカス可能にします。
a11y/label-has-for 悪い · 良い label を対象のフォーム部品と関連付けます。
a11y/landmark-roles 悪い · 良い ランドマーク role の配置と重複を検査します。
a11y/media-has-caption 悪い · 良い 音声・動画に字幕を用意します。
a11y/mouse-events-have-key-events 悪い · 良い マウス操作と対応する focus / blur 操作を用意します。
a11y/no-access-key 悪い · 良い 環境のショートカットと衝突し得る accesskey を検出します。
a11y/no-aria-hidden-on-focusable 悪い · 良い フォーカス可能な要素を aria-hidden で支援技術から隠す指定を検出します。
a11y/no-autofocus 悪い · 良い 意図せずフォーカスを移動させる autofocus を検出します。
a11y/no-distracting-elements 悪い · 良い marquee や blink などの注意をそらす要素を検出します。
a11y/no-i-for-icon 悪い · 良い アイコン用の i 要素を検出し、意味に合う要素を勧めます。
a11y/no-redundant-roles 悪い · 良い 要素本来の意味と重複する ARIA role を検出します。
a11y/no-refer-to-non-existent-id 悪い · 良い 文書内に存在しない ID への参照を検出します。
a11y/no-role-presentation-on-focusable 悪い · 良い フォーカス可能な要素への role="presentation" または role="none" の指定を検出します。
a11y/no-static-element-interactions 悪い · 良い 操作部品ではない要素へのイベント指定を検出します。
a11y/placeholder-label-option 悪い · 良い required の select を値が空のプレースホルダー option から始めます。
a11y/role-has-required-aria-props 悪い · 良い ARIA role が必要とする属性を指定します。
a11y/tabindex-no-positive 悪い · 良い 通常のフォーカス順序を変える正の tabindex を検出します。
a11y/use-list 悪い · 良い 箇条書きに見えるテキストをリスト要素で表現します。
vue/use-unique-element-ids 悪い · 良い 静的 ID の代わりに useId() で一意な ID を生成します。

全ルール · ルールのオプション · ESLint 移行対応表 · プロジェクトの検査 · 子への属性の継承

a11y/alt-text

画像などのメディアに代替テキストを用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/alt-text": "warn"
      }
    },
  },
});
vp run lint

悪い

画像の送信ボタンには URL しかなく、操作を説明する alt がありません。

<template>
  <input type="image" src="/submit.png" />
</template>

良い

alt="Submit search" を追加し、検索を送信する操作を説明する名前を支援技術に伝えます。

<template>
  <input type="image" src="/submit.png" alt="Submit search" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/anchor-has-content

リンクに支援技術で読める内容を用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/anchor-has-content": "warn"
      }
    },
  },
});
vp run lint

悪い

/settings へのリンクが空で、移動先を説明する内容がありません。

<template>
  <a href="/settings"></a>
</template>

良い

同じリンクに Settings の文字を入れ、移動先を示します。

<template>
  <a href="/settings">Settings</a>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/anchor-is-valid

リンクの href に有効な移動先を指定します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/anchor-is-valid": "warn"
      }
    },
  },
});
vp run lint

悪い

一つ目は操作に # を使い、二つ目は JavaScript URL を使っています。どちらも通常の移動先を持つリンクではありません。

<template>
  <a href="#" @click="openPanel">Open panel</a>
  <a href="JaVaScRiPt:void(0)">Run action</a>
</template>

良い

openPanel は button で実行し、リンクには実際の移動先 /docs/javascript-urls を指定します。

<template>
  <button type="button" @click="openPanel">Open panel</button>
  <a href="/docs/javascript-urls">JavaScript URL guide</a>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/aria-props

存在しない ARIA 属性を検出します。

悪い例 · 良い例

既定の重大度: error
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/aria-props": "error"
      }
    },
  },
});
vp run lint

悪い

aria-lable は綴りが誤っており、有効な ARIA 属性ではありません。

<template>
  <button aria-lable="Save changes">Save</button>
</template>

良い

正しい aria-label に変更してボタンの名前を指定します。

<template>
  <button aria-label="Save changes">Save</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/aria-role

抽象ロールを除く、有効な ARIA role を指定します。

悪い例 · 良い例

既定の重大度: error
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/aria-role": "error"
      }
    },
  },
});
vp run lint

悪い

datepicker は有効な ARIA ロールではありません。

<template>
  <section role="datepicker">...</section>
</template>

良い

有効な ARIA ロールである dialog を使い、日付を選択する領域の名前も指定します。

<template>
  <section role="dialog" aria-label="Choose a date">...</section>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/aria-unsupported-elements

ARIA 属性を使用できない要素への指定を検出します。

悪い例 · 良い例

既定の重大度: error
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/aria-unsupported-elements": "error"
      }
    },
  },
});
vp run lint

悪い

ARIA 属性を使えない meta に aria-hidden を指定しています。

<template>
  <meta charset="utf-8" aria-hidden="true" />
</template>

良い

ARIA 属性だけを取り除き、文字コードの宣言は維持します。

<template>
  <meta charset="utf-8" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/click-events-have-key-events

クリックで操作する要素にキーボード操作も用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

対話的な役割を持たない通常要素が対象です。button や対話的な ARIA role を持つ要素はこの検出の対象外です。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/click-events-have-key-events": "warn"
      }
    },
  },
});
vp run lint

悪い

通常の div にクリックハンドラーだけを指定し、キーボード操作に対応していません。

<template>
<div @click="activate">Activate</div>
</template>

良い

同じ activate を button に指定し、標準のキーボード操作を使います。

<template>
<button @click="activate">Activate</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/form-control-has-label

フォーム部品に関連付けられたラベルを用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/form-control-has-label": "warn"
      }
    },
  },
});
vp run lint

悪い

検索欄に入力内容を説明する label がありません。

<template>
  <input type="search" />
</template>

良い

入力欄を label で囲み、Search の文字と関連付けます。

<template>
  <label>
    Search
    <input type="search" />
  </label>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/heading-has-content

見出しに支援技術で読める内容を用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/heading-has-content": "warn"
      }
    },
  },
});
vp run lint

悪い

h2 でレベル 2 の見出しを宣言していますが、見出しの内容が空です。

<template>
  <h2></h2>
</template>

良い

同じ h2 に Billing settings の内容を入れます。

<template>
  <h2>Billing settings</h2>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/heading-levels

見出しの階層を飛ばした指定を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: nuxt, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/heading-levels": "warn"
      }
    },
  },
});
vp run lint

悪い

見出しが h1 から h3 に飛び、レベル 2 を省略しています。

<template>
  <h1>Account</h1>
  <h3>Billing</h3>
</template>

良い

請求設定の見出しを h2 にし、階層を順に並べます。

<template>
  <h1>Account</h1>
  <h2>Billing</h2>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/iframe-has-title

iframe に内容を説明する title を指定します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/iframe-has-title": "warn"
      }
    },
  },
});
vp run lint

悪い

決済画面の iframe に URL はありますが、内容を説明する title がありません。

<template>
  <iframe src="/checkout"></iframe>
</template>

良い

title="Checkout preview" で iframe の内容を説明します。

<template>
  <iframe src="/checkout" title="Checkout preview"></iframe>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/img-alt

画像に alt 属性を指定します。装飾画像は空の alt を使います。

悪い例 · 良い例

既定の重大度: warning
プリセット: none
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/img-alt": "warn"
      }
    },
  },
});
vp run lint

悪い

アバター画像に alt 属性がなく、代替テキストが指定されていません。

<template>
  <img src="/avatar.png" />
</template>

良い

alt="User avatar" で画像の代わりとなる文字を指定します。

<template>
  <img src="/avatar.png" alt="User avatar" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/interactive-supports-focus

操作可能な role の要素をフォーカス可能にします。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/interactive-supports-focus": "warn"
      }
    },
  },
});
vp run lint

悪い

span に button のロールとクリックハンドラーを付けても、キーボードでフォーカスできる要素にはなりません。

<template>
  <span role="button" @click="open">Open</span>
</template>

良い

フォーカスできる標準の button に変更し、同じ open を実行します。

<template>
  <button type="button" @click="open">Open</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/label-has-for

label を対象のフォーム部品と関連付けます。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/label-has-for": "warn"
      }
    },
  },
});
vp run lint

悪い

離れた label に for がなく、入力欄を囲んでもいないため関連付けがありません。

<template>
  <label>Email</label>
  <input id="email" />
</template>

良い

for="email" を入力欄の ID と一致させて関連付けます。

<template>
  <label for="email">Email</label>
  <input id="email" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/landmark-roles

ランドマーク role の配置と重複を検査します。

悪い例 · 良い例

既定の重大度: warning
プリセット: nuxt, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/landmark-roles": "warn"
      }
    },
  },
});
vp run lint

悪い

同じテンプレートに main が二つあり、主要な領域が重複しています。

<template>
  <main>Dashboard</main>
  <main>Settings</main>
</template>

良い

Dashboard を main として残し、Settings を名前付きの nav に変更します。

<template>
  <main>Dashboard</main>
  <nav aria-label="Settings">...</nav>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/media-has-caption

音声・動画に字幕を用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/media-has-caption": "warn"
      }
    },
  },
});
vp run lint

悪い

動画に再生操作はありますが、字幕の track がありません。

<template>
  <video src="/demo.mp4" controls />
</template>

良い

同じ動画に kind="captions" の track を追加して英語の字幕を指定します。

<template>
  <video src="/demo.mp4" controls>
    <track kind="captions" src="/demo.en.vtt" srclang="en" label="English" />
  </video>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/mouse-events-have-key-events

マウス操作と対応する focus / blur 操作を用意します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/mouse-events-have-key-events": "warn"
      }
    },
  },
});
vp run lint

悪い

プレビューの表示切り替えを mouseenter と mouseleave だけに指定しています。

<template>
  <div @mouseenter="showPreview" @mouseleave="hidePreview">Preview</div>
</template>

良い

フォーカスできる button で、同じ操作を focus と blur からも実行します。

<template>
  <button
    type="button"
    @focus="showPreview"
    @blur="hidePreview"
    @mouseenter="showPreview"
    @mouseleave="hidePreview"
  >
    Preview
  </button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-access-key

環境のショートカットと衝突し得る accesskey を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-access-key": "warn"
      }
    },
  },
});
vp run lint

悪い

accesskey="s" がブラウザーや支援技術のショートカットと競合する可能性があります。

<template>
  <button accesskey="s">Save</button>
</template>

良い

accesskey を取り除き、通常の Save ボタンは残します。

<template>
  <button>Save</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-aria-hidden-on-focusable

フォーカス可能な要素を aria-hidden で支援技術から隠す指定を検出します。

悪い例 · 良い例

既定の重大度: error
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-aria-hidden-on-focusable": "error"
      }
    },
  },
});
vp run lint

悪い

フォーカスできる Close ボタンを aria-hidden="true" でアクセシビリティ ツリーから隠しています。

<template>
  <button aria-hidden="true" @click="close">Close</button>
</template>

良い

aria-hidden を取り除いてボタンを支援技術から参照できる状態にし、aria-label に Close を指定します。

<template>
  <button aria-label="Close" @click="close">Close</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-autofocus

意図せずフォーカスを移動させる autofocus を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-autofocus": "warn"
      }
    },
  },
});
vp run lint

悪い

検索の入力欄に autofocus があり、表示時に利用者の操作なしでフォーカスを要求します。

<template>
  <input autofocus name="query" />
</template>

良い

autofocus を取り除き、検索欄はそのまま残します。

<template>
  <input name="query" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-distracting-elements

marquee や blink などの注意をそらす要素を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-distracting-elements": "warn"
      }
    },
  },
});
vp run lint

悪い

marquee を使って文字を自動的に動かしています。

<template>
  <marquee>Limited offer</marquee>
</template>

良い

同じ案内を p に入れ、自動的に動く要素を使いません。

<template>
  <p>Limited offer</p>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-i-for-icon

アイコン用の i 要素を検出し、意味に合う要素を勧めます。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-i-for-icon": "warn"
      }
    },
  },
});
vp run lint

悪い

アイコンの表示に i 要素を使っています。i が持つテキスト上の意味は、アイコンだけのボタンが行う操作を説明するものではありません。

<template>
  <button>
    <i class="material-icons">delete</i>
  </button>
</template>

良い

装飾用の span に aria-hidden を指定してアイコンを支援技術から隠し、別の Delete item の文字でボタンの操作を説明します。

<template>
  <button>
    <span class="material-icons" aria-hidden="true">delete</span>
    <span class="sr-only">Delete item</span>
  </button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-redundant-roles

要素本来の意味と重複する ARIA role を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: 対応している診断で利用できます
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-redundant-roles": "warn"
      }
    },
  },
});
vp run lint

悪い

button は元から button の役割を持つため、同じ role を重複して指定しています。

<template>
  <button role="button">Save</button>
</template>

良い

重複する role を取り除き、HTML の標準の役割を使います。

<template>
  <button>Save</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

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

文書内に存在しない ID への参照を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-refer-to-non-existent-id": "warn"
      }
    },
  },
});
vp run lint

悪い

aria-labelledby が save-label を参照していますが、その ID の要素がありません。

<template>
  <button aria-labelledby="save-label">Save</button>
</template>

良い

一致する ID の span を追加し、ボタンの名前を参照できるようにします。

<template>
  <span id="save-label">Save changes</span>
  <button aria-labelledby="save-label">Save</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-role-presentation-on-focusable

フォーカス可能な要素への role="presentation" または role="none" の指定を検出します。

悪い例 · 良い例

既定の重大度: error
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-role-presentation-on-focusable": "error"
      }
    },
  },
});
vp run lint

悪い

フォーカスできる Billing のリンクに role="presentation" を指定しています。リンク本来の操作可能な役割と矛盾するため、ブラウザーはこの presentation の指定を無視する必要があります。

<template>
  <a href="/billing" role="presentation">Billing</a>
</template>

良い

矛盾する presentation の指定を除き、Billing への標準のリンクの役割を使います。

<template>
  <a href="/billing">Billing</a>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/no-static-element-interactions

操作部品ではない要素へのイベント指定を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/no-static-element-interactions": "warn"
      }
    },
  },
});
vp run lint

悪い

操作の役割がない section に Enter キーの操作を指定しています。

<template>
  <section @keydown.enter="select">Select</section>
</template>

良い

同じ Enter キーの操作を標準の button に指定し、要素自体に操作の意味を持たせます。

<template>
  <button type="button" @keydown.enter="select">Select</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/placeholder-label-option

required の select を値が空のプレースホルダー option から始めます。

悪い例 · 良い例

既定の重大度: warning
プリセット: nuxt, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/placeholder-label-option": "warn"
      }
    },
  },
});
vp run lint

悪い

select は required ですが、最初の option が Japan のため、国が選ばれた状態でフォームが始まり、required が送信を止めることはありません。

<template>
  <select v-model="country" required>
    <option value="jp">Japan</option>
    <option value="fr">France</option>
  </select>
</template>

良い

値が空の最初の option がプレースホルダーになり、select は値のない状態から始まるため、required によって国の選択が必要になります。

<template>
  <select v-model="country" required>
    <option value="">Choose a country</option>
    <option value="jp">Japan</option>
  </select>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/role-has-required-aria-props

ARIA role が必要とする属性を指定します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/role-has-required-aria-props": "warn"
      }
    },
  },
});
vp run lint

悪い

checkbox の role に、選択状態を示す aria-checked がありません。

<template>
  <span role="checkbox">Receive updates</span>
</template>

良い

aria-checked="false" を追加し、checkbox に必要な状態を指定します。

<template>
  <span role="checkbox" aria-checked="false">Receive updates</span>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/tabindex-no-positive

通常のフォーカス順序を変える正の tabindex を検出します。

悪い例 · 良い例

既定の重大度: warning
プリセット: happy-path, nuxt, ecosystem, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/tabindex-no-positive": "warn"
      }
    },
  },
});
vp run lint

悪い

tabindex に正の値 3 を指定し、通常の操作要素より先にフォーカスが移動するようにしています。

<template>
  <button tabindex="3">Save</button>
</template>

良い

正の tabindex を取り除き、button の標準のフォーカス順を使います。

<template>
  <button>Save</button>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

a11y/use-list

箇条書きに見えるテキストをリスト要素で表現します。

悪い例 · 良い例

既定の重大度: warning
プリセット: nuxt, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "a11y/use-list": "warn"
      }
    },
  },
});
vp run lint

悪い

タスクを p と文字のハイフンで並べており、リストの要素を使っていません。

<template>
  <p>- First task</p>
  <p>- Second task</p>
</template>

良い

同じタスクを ul と li に入れ、リストとして表します。

<template>
  <ul>
    <li>First task</li>
    <li>Second task</li>
  </ul>
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール

vue/use-unique-element-ids

静的 ID の代わりに useId() で一意な ID を生成します。

悪い例 · 良い例

既定の重大度: warning
プリセット: nuxt, opinionated
自動修正: なし。修正内容を確認してください
適用範囲: Vue SFC のテンプレートと各ブロック。ルールに必要な script の文脈も例に含めています。
オプション: ルール固有のオプションはありません。重大度とプリセットは設定できます。

設定(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "vue/use-unique-element-ids": "warn"
      }
    },
  },
});
vp run lint

悪い

固定の email ID がコンポーネントの各インスタンスで重複し、複数表示時に label の参照先が曖昧になります。

<template>
  <label for="email">Email</label>
  <input id="email" />
</template>

良い

useId() の emailId を label の for と input の id の両方にバインドします。

<script setup>
import { useId } from "vue";

const emailId = useId();
</script>

<template>
  <label :for="emailId">Email</label>
  <input :id="emailId" />
</template>

良い例は上記の設定でこのルールの診断が出ない例です。他のルールの診断は出る場合があります。

実装 · 全ルール