Vize

Règles d’accessibilité

Chaque règle présente sur cette page son objectif, sa configuration et ses exemples complets Mauvais et Bon, accompagnés de leurs explications. Les lignes surlignées montrent les modifications ; le code copié conserve la source complète. Les limites de prise en charge actuelles sont précisées avant les exemples concernés.

Règle Exemples Objectif
a11y/alt-text Mauvais · Bon Exiger un texte alternatif pour les éléments multimédias
a11y/anchor-has-content Mauvais · Bon Exiger un contenu accessible pour les éléments de lien
a11y/anchor-is-valid Mauvais · Bon Imposer un href valide sur les éléments de lien
a11y/aria-props Mauvais · Bon Interdire les attributs ARIA invalides
a11y/aria-role Mauvais · Bon Exiger un rôle ARIA valide et non abstrait pour les éléments possédant un rôle ARIA
a11y/aria-unsupported-elements Mauvais · Bon Interdire les attributs ARIA sur les éléments qui ne les prennent pas en charge
a11y/click-events-have-key-events Mauvais · Bon Exiger des gestionnaires de clavier avec les événements de clic
a11y/form-control-has-label Mauvais · Bon Exiger des libellés associés aux contrôles de formulaire
a11y/heading-has-content Mauvais · Bon Exiger un contenu accessible pour les éléments de titre
a11y/heading-levels Mauvais · Bon Interdire de sauter des niveaux de titre
a11y/iframe-has-title Mauvais · Bon Exiger un attribut title sur les éléments iframe
a11y/img-alt Mauvais · Bon Exiger un attribut alt sur les images pour les rendre accessibles
a11y/interactive-supports-focus Mauvais · Bon Exiger que les éléments possédant un rôle interactif puissent recevoir le focus
a11y/label-has-for Mauvais · Bon Exiger des contrôles de formulaire associés aux libellés
a11y/landmark-roles Mauvais · Bon Valider l’emplacement et l’unicité des rôles de zones de repère
a11y/media-has-caption Mauvais · Bon Exiger des sous-titres pour les éléments multimédias
a11y/mouse-events-have-key-events Mauvais · Bon Exiger des événements de focus et de perte du focus avec les événements de souris
a11y/no-access-key Mauvais · Bon Interdire l’utilisation de l’attribut accesskey
a11y/no-aria-hidden-on-focusable Mauvais · Bon Interdire aria-hidden="true" sur les éléments pouvant recevoir le focus
a11y/no-autofocus Mauvais · Bon Interdire l’utilisation de l’attribut autofocus
a11y/no-distracting-elements Mauvais · Bon Interdire les éléments distrayants tels que <marquee> et <blink>
a11y/no-i-for-icon Mauvais · Bon Interdire l’élément <i> pour les icônes
a11y/no-redundant-roles Mauvais · Bon Interdire les rôles ARIA redondants
a11y/no-refer-to-non-existent-id Mauvais · Bon Interdire les références à des identifiants inexistants
a11y/no-role-presentation-on-focusable Mauvais · Bon Interdire role="presentation" ou role="none" sur les éléments pouvant recevoir le focus
a11y/no-static-element-interactions Mauvais · Bon Interdire les gestionnaires d’événements sur les éléments statiques
a11y/placeholder-label-option Mauvais · Bon Exiger une option d’invite dans un select required
a11y/role-has-required-aria-props Mauvais · Bon Exiger les propriétés obligatoires des rôles ARIA
a11y/tabindex-no-positive Mauvais · Bon Interdire les valeurs positives de tabindex
a11y/use-list Mauvais · Bon Suggérer des éléments de liste pour les textes ressemblant à des listes à puces
vue/use-unique-element-ids Mauvais · Bon Imposer des identifiants d’éléments uniques avec useId() plutôt que des littéraux statiques

Toutes les règles · Options des règles · Correspondance de migration ESLint · Vérifications du projet · Attributs entre composants

a11y/alt-text

Exiger un texte alternatif pour les éléments multimédias

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

Le contrôle de soumission sous forme d’image ne fournit que l’URL de son image ; il n’a pas de texte alt décrivant l’action.

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

Bon

alt="Submit search" donne au contrôle image un nom accessible décrivant la soumission de la recherche.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/anchor-has-content

Exiger un contenu accessible pour les éléments de lien

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le lien /settings n’a ni texte ni autre contenu servant à le nommer ; sa destination n’a donc aucune description accessible.

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

Bon

Le texte visible Settings fournit le contenu du lien vers la même destination.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/anchor-is-valid

Imposer un href valide sur les éléments de lien

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le premier lien utilise # pour une action ; le second utilise une URL JavaScript. Aucun ne fournit une destination de navigation ordinaire.

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

Bon

Un bouton natif exécute openPanel, tandis que le lien restant possède la destination réelle /docs/javascript-urls.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/aria-props

Interdire les attributs ARIA invalides

Mauvais · Bon

Gravité par défaut: error
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

aria-lable est mal orthographié et n’est pas un attribut ARIA pris en charge.

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

Bon

L’attribut pris en charge aria-label fournit le nom du bouton.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/aria-role

Exiger un rôle ARIA valide et non abstrait pour les éléments possédant un rôle ARIA

Mauvais · Bon

Gravité par défaut: error
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

datepicker n’est pas un rôle ARIA reconnu pour cette section.

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

Bon

La section utilise le rôle reconnu dialog et un libellé décrivant la sélection de la date.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/aria-unsupported-elements

Interdire les attributs ARIA sur les éléments qui ne les prennent pas en charge

Mauvais · Bon

Gravité par défaut: error
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

L’élément de métadonnées porte aria-hidden, alors que meta ne prend pas en charge les attributs ARIA.

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

Bon

Supprimer l’attribut ARIA conserve intacte la déclaration de jeu de caractères.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/click-events-have-key-events

Exiger des gestionnaires de clavier avec les événements de clic

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Contrôle les éléments non interactifs sans rôle interactif. Les boutons natifs et les éléments possédant un rôle ARIA interactif sont hors du champ du diagnostic de cette règle.

Configuration (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

Mauvais

Le div non interactif possède un gestionnaire de clic, mais aucune gestion des événements de clavier.

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

Bon

Un button natif permet une activation au clavier avec le même gestionnaire activate.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/form-control-has-label

Exiger des libellés associés aux contrôles de formulaire

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le champ de recherche n’a pas de libellé indiquant ce que l’utilisateur doit saisir.

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

Bon

Envelopper le champ dans un label associe le texte visible Search au contrôle.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/heading-has-content

Exiger un contenu accessible pour les éléments de titre

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le h2 apporte un niveau de titre, mais ne contient aucun texte de titre.

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

Bon

Billing settings fournit le contenu du titre de niveau deux existant.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/heading-levels

Interdire de sauter des niveaux de titre

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

La séquence des titres passe directement de h1 à h3, sans niveau deux.

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

Bon

Remplacer le titre de facturation par h2 conserve une hiérarchie de titres consécutive.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/iframe-has-title

Exiger un attribut title sur les éléments iframe

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le cadre de paiement possède une URL source, mais aucun title décrivant le contenu intégré.

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

Bon

title="Checkout preview" nomme le contenu de ce cadre.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/img-alt

Exiger un attribut alt sur les images pour les rendre accessibles

Mauvais · Bon

Gravité par défaut: warning
Préréglages: none
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

L’image de l’avatar ne possède pas d’attribut alt.

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

Bon

alt="User avatar" fournit une alternative textuelle à l’avatar.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/interactive-supports-focus

Exiger que les éléments possédant un rôle interactif puissent recevoir le focus

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Donner à un span le rôle button et un gestionnaire de clic ne rend pas l’élément accessible au focus clavier.

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

Bon

Le bouton natif peut recevoir le focus et conserve la même action open.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/label-has-for

Exiger des contrôles de formulaire associés aux libellés

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le label séparé n’est ni associé au moyen de for ni placé autour du champ.

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

Bon

for="email" correspond à l’identifiant du champ et associe explicitement les deux éléments.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/landmark-roles

Valider l’emplacement et l’unicité des rôles de zones de repère

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

Deux éléments main déclarent des zones principales en double dans le même template.

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

Bon

Le tableau de bord reste la zone principale ; la zone des paramètres devient une zone de navigation nommée.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/media-has-caption

Exiger des sous-titres pour les éléments multimédias

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

La vidéo possède des contrôles de lecture, mais aucune piste de sous-titres.

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

Bon

Un track avec kind="captions" fournit les sous-titres anglais de la même vidéo.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/mouse-events-have-key-events

Exiger des événements de focus et de perte du focus avec les événements de souris

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

La visibilité de l’aperçu change uniquement avec les gestionnaires d’entrée et de sortie de la souris.

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

Bon

Les mêmes actions d’aperçu s’exécutent lors du focus et de sa perte, et le bouton peut recevoir le focus clavier.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-access-key

Interdire l’utilisation de l’attribut accesskey

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le raccourci accesskey="s" peut entrer en conflit avec les raccourcis du navigateur ou des technologies d’assistance.

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

Bon

Supprimer accesskey conserve le bouton Save ordinaire.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-aria-hidden-on-focusable

Interdire aria-hidden="true" sur les éléments pouvant recevoir le focus

Mauvais · Bon

Gravité par défaut: error
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le bouton Close pouvant recevoir le focus est masqué dans l’arbre d’accessibilité avec aria-hidden="true".

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

Bon

Le bouton reste exposé et reçoit un libellé Close au lieu d’être masqué.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-autofocus

Interdire l’utilisation de l’attribut autofocus

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

Le champ demande à recevoir automatiquement le focus lorsqu’il apparaît.

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

Bon

Supprimer autofocus évite cette demande de focus automatique tout en conservant le champ de requête.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-distracting-elements

Interdire les éléments distrayants tels que <marquee> et <blink>

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

L’élément marquee introduit un texte en mouvement automatique.

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

Bon

Un paragraphe affiche la même offre sans l’élément marquee distrayant.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-i-for-icon

Interdire l’élément <i> pour les icônes

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

L’icône est affichée avec i, dont la sémantique textuelle ne décrit pas une action représentée uniquement par une icône.

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

Bon

Un span décoratif masque le glyphe de l’icône, tandis que le texte séparé Delete item nomme l’action du bouton.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-redundant-roles

Interdire les rôles ARIA redondants

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Disponible pour les diagnostics pris en charge
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le bouton natif possède déjà le rôle button ; role="button" répète donc sa sémantique implicite.

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

Bon

Supprimer le rôle répété conserve la sémantique du bouton fournie par HTML.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

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

Interdire les références à des identifiants inexistants

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

aria-labelledby pointe vers save-label, mais aucun élément ne déclare cet identifiant.

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

Bon

Ajouter le span correspondant résout la référence et fournit le libellé du bouton.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-role-presentation-on-focusable

Interdire role="presentation" ou role="none" sur les éléments pouvant recevoir le focus

Mauvais · Bon

Gravité par défaut: error
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le lien de facturation pouvant recevoir le focus demande role=presentation, ce qui entre en conflit avec son rôle de lien interactif ; les navigateurs doivent ignorer cette demande de présentation.

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

Bon

Supprimez la demande de présentation contradictoire et utilisez le rôle de lien natif ainsi que la destination de facturation.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/no-static-element-interactions

Interdire les gestionnaires d’événements sur les éléments statiques

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Une section statique reçoit une action liée à la touche Entrée sans posséder de rôle interactif.

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

Bon

Un bouton natif porte la même action dans un élément interactif approprié.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/placeholder-label-option

Exiger une option d’invite dans un select required

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le select est required, mais sa première option est Japan : le formulaire démarre avec un pays déjà choisi et required ne bloque jamais l’envoi.

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

Bon

Une première option vide sert d’invite : le select démarre sans valeur, et required oblige à choisir un pays.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/role-has-required-aria-props

Exiger les propriétés obligatoires des rôles ARIA

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Le rôle checkbox omet aria-checked, qui communique l’état de la case à cocher.

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

Bon

aria-checked="false" fournit l’état exigé par le rôle checkbox.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/tabindex-no-positive

Interdire les valeurs positives de tabindex

Mauvais · Bon

Gravité par défaut: warning
Préréglages: happy-path, nuxt, ecosystem, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

Un tabindex positif de 3 crée un ordre de focus personnalisé avant les contrôles ordinaires.

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

Bon

Le bouton utilise son ordre de focus natif sans tabindex positif.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

a11y/use-list

Suggérer des éléments de liste pour les textes ressemblant à des listes à puces

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (Vite+)

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

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

Mauvais

Les tâches sont des paragraphes séparés précédés de tirets saisis, plutôt que des éléments de liste.

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

Bon

Une liste non ordonnée et ses éléments expriment les mêmes tâches avec une sémantique de liste.

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles

vue/use-unique-element-ids

Imposer des identifiants d’éléments uniques avec useId() plutôt que des littéraux statiques

Mauvais · Bon

Gravité par défaut: warning
Préréglages: nuxt, opinionated
Correction automatique: Aucune ; examinez la modification proposée
Champ d’application: Templates et blocs des SFC Vue, avec le contexte du script requis par la règle
Options: Aucune option propre à la règle. La gravité et le choix des préréglages sont configurables.

Configuration (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

Mauvais

L’identifiant littéral email est réutilisé par chaque instance de ce composant, ce qui peut faire pointer son label vers la mauvaise instance lorsque plusieurs sont affichées.

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

Bon

useId() produit l’emailId de l’instance ; liez la même valeur au for du label et à l’id de l’input.

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

const emailId = useId();
</script>

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

Le bon exemple évite le diagnostic de cette règle avec la configuration ci-dessus ; d’autres règles peuvent encore signaler des diagnostics.

Implémentation · Toutes les règles