Vize

アクセシビリティ情報の整合性

このルール群では、テンプレートの role、フォーカスの順序、ラベル、要素同士の対応に矛盾がないかを確認します。 ARIA の role を追加したときや、操作に使う要素を変更したときに、関連する属性や要素の関係を見直してください。

たとえば、role に必要な ARIA 属性では、role に必要な属性が不足した場合の変更例を確認できます。 悪い例と良い例を比較し、掲載された設定でルールを有効にして、vp run lint を実行してください。 アクセシビリティの全ルールでは、ほかの検査も確認できます。

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

ルール 例 目的
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/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>

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

実装 · 全ルール