Vize

Regras de Acessibilidade

Cada regra desta categoria reúne nesta página sua finalidade, configuração e exemplos incorreto e correto completos. Os exemplos de projeto também incluem os arquivos compartilhados, que devem ser usados nos dois casos. As linhas destacadas mostram a alteração; o código copiado preserva o conteúdo completo. As notas de suporte distinguem os diagnósticos disponíveis das convenções ilustrativas e dos contratos sem produtor atual; ativar um ID não implementa uma verificação ausente.

Regra Exemplos Finalidade
a11y/alt-text Incorreto · Correto Exigir texto alternativo para elementos de mídia
a11y/anchor-has-content Incorreto · Correto Exigir conteúdo acessível nos elementos de âncora
a11y/anchor-is-valid Incorreto · Correto Exigir um href válido nos elementos de âncora
a11y/aria-props Incorreto · Correto Proibir atributos ARIA inválidos
a11y/aria-role Incorreto · Correto Exigir que elementos com papéis ARIA usem um papel ARIA válido e não abstrato
a11y/aria-unsupported-elements Incorreto · Correto Proibir atributos ARIA em elementos que não os aceitam
a11y/click-events-have-key-events Incorreto · Correto Exigir manipuladores de eventos de teclado junto aos eventos de clique
a11y/form-control-has-label Incorreto · Correto Exigir rótulos associados aos controles de formulário
a11y/heading-has-content Incorreto · Correto Exigir conteúdo acessível nos elementos de título
a11y/heading-levels Incorreto · Correto Proibir que níveis de título sejam pulados
a11y/iframe-has-title Incorreto · Correto Exigir um atributo title nos elementos iframe
a11y/img-alt Incorreto · Correto Exigir o atributo alt nas imagens para garantir acessibilidade
a11y/interactive-supports-focus Incorreto · Correto Exigir que elementos com papéis interativos possam receber foco
a11y/label-has-for Incorreto · Correto Exigir controles de formulário associados aos rótulos
a11y/landmark-roles Incorreto · Correto Validar a posição e a unicidade dos papéis de regiões de referência
a11y/media-has-caption Incorreto · Correto Exigir legendas nos elementos de mídia
a11y/mouse-events-have-key-events Incorreto · Correto Exigir eventos de foco e perda de foco junto aos eventos de mouse
a11y/no-access-key Incorreto · Correto Proibir o uso do atributo accesskey
a11y/no-aria-hidden-on-focusable Incorreto · Correto Proibir aria-hidden="true" em elementos que podem receber foco
a11y/no-autofocus Incorreto · Correto Proibir o uso do atributo autofocus
a11y/no-distracting-elements Incorreto · Correto Proibir elementos que causam distração, como <marquee> e <blink>
a11y/no-i-for-icon Incorreto · Correto Proibir o uso do elemento <i> para ícones
a11y/no-redundant-roles Incorreto · Correto Proibir papéis ARIA redundantes
a11y/no-refer-to-non-existent-id Incorreto · Correto Proibir referências a IDs inexistentes
a11y/no-role-presentation-on-focusable Incorreto · Correto Proibir role="presentation" ou role="none" em elementos que podem receber foco
a11y/no-static-element-interactions Incorreto · Correto Proibir manipuladores de eventos em elementos estáticos
a11y/placeholder-label-option Incorreto · Correto Exigir uma opção de orientação em um select required
a11y/role-has-required-aria-props Incorreto · Correto Exigir as propriedades obrigatórias dos papéis ARIA
a11y/tabindex-no-positive Incorreto · Correto Proibir valores positivos de tabindex
a11y/use-list Incorreto · Correto Sugerir elementos de lista para textos que parecem itens de lista
vue/use-unique-element-ids Incorreto · Correto Exigir IDs de elementos únicos por meio de useId(), em vez de literais estáticos

Todas as regras · Opções das regras · Mapa de migração do ESLint · Verificações do projeto · Atributos entre componentes

a11y/alt-text

Exigir texto alternativo para elementos de mídia

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

O controle de envio com imagem fornece apenas a URL da imagem; ele não tem texto alt que descreva a ação.

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

Correto

alt="Submit search" dá ao controle com imagem um nome acessível que descreve o envio da pesquisa.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/anchor-has-content

Exigir conteúdo acessível nos elementos de âncora

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O link /settings não tem texto nem outro conteúdo que lhe dê um nome, então seu destino não tem uma descrição acessível.

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

Correto

O texto visível Settings fornece conteúdo para o link com o mesmo destino.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/anchor-is-valid

Exigir um href válido nos elementos de âncora

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

A primeira âncora usa # para uma ação; a segunda usa uma URL JavaScript. Nenhuma fornece um destino de navegação comum.

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

Correto

Um botão nativo executa openPanel, enquanto a âncora restante tem o destino real /docs/javascript-urls.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/aria-props

Proibir atributos ARIA inválidos

Incorreto · Correto

Severidade padrão: error
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

aria-lable está escrito incorretamente e não é um atributo ARIA aceito.

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

Correto

O atributo aceito aria-label fornece o nome do botão.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/aria-role

Exigir que elementos com papéis ARIA usem um papel ARIA válido e não abstrato

Incorreto · Correto

Severidade padrão: error
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

datepicker não é um papel ARIA reconhecido para esta seção.

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

Correto

A seção usa o papel reconhecido dialog e um rótulo que descreve a seleção da data.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/aria-unsupported-elements

Proibir atributos ARIA em elementos que não os aceitam

Incorreto · Correto

Severidade padrão: error
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O elemento de metadados tem aria-hidden, embora meta não aceite atributos ARIA.

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

Correto

Remover o atributo ARIA mantém intacta a declaração do conjunto de caracteres.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/click-events-have-key-events

Exigir manipuladores de eventos de teclado junto aos eventos de clique

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Verifica elementos não interativos sem uma função interativa. Botões nativos e elementos com uma função ARIA interativa ficam fora dos diagnósticos desta regra.

Configuração (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

Incorreto

A div não interativa tem um manipulador de clique, mas não trata eventos de teclado.

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

Correto

Um button nativo permite a ativação pelo teclado para o mesmo manipulador activate.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/form-control-has-label

Exigir rótulos associados aos controles de formulário

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O campo de pesquisa não tem um rótulo que identifique o que o usuário deve inserir.

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

Correto

Envolver o campo em um rótulo associa o texto visível Search ao controle.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/heading-has-content

Exigir conteúdo acessível nos elementos de título

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O h2 acrescenta um nível de título, mas não tem conteúdo de título.

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

Correto

Billing settings fornece o conteúdo do título de nível dois existente.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/heading-levels

Proibir que níveis de título sejam pulados

Incorreto · Correto

Severidade padrão: warning
Predefinições: nuxt, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

A sequência de títulos passa diretamente de h1 para h3, pulando o nível dois.

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

Correto

Alterar o título de cobrança para h2 preserva uma hierarquia consecutiva de títulos.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/iframe-has-title

Exigir um atributo title nos elementos iframe

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O quadro de finalização de compra tem uma URL de origem, mas não tem um title que descreva o conteúdo incorporado.

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

Correto

title="Checkout preview" dá um nome ao conteúdo desse quadro.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/img-alt

Exigir o atributo alt nas imagens para garantir acessibilidade

Incorreto · Correto

Severidade padrão: warning
Predefinições: none
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

A imagem do avatar não tem o atributo alt.

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

Correto

alt="User avatar" fornece uma alternativa textual para o avatar.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/interactive-supports-focus

Exigir que elementos com papéis interativos possam receber foco

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

Atribuir a um span o papel de botão e um manipulador de clique não permite que o elemento receba foco pelo teclado.

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

Correto

O botão nativo pode receber foco e mantém a mesma ação open.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/label-has-for

Exigir controles de formulário associados aos rótulos

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O rótulo separado não está associado por meio de for nem envolve o campo.

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

Correto

for="email" corresponde ao ID do campo e associa explicitamente os dois elementos.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/landmark-roles

Validar a posição e a unicidade dos papéis de regiões de referência

Incorreto · Correto

Severidade padrão: warning
Predefinições: nuxt, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

Dois elementos main declaram regiões de referência principais duplicadas no mesmo template.

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

Correto

O painel permanece como a região de referência principal; a área de configurações se torna uma região de referência de navegação com nome.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/media-has-caption

Exigir legendas nos elementos de mídia

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O vídeo tem controles de reprodução, mas não tem uma faixa de legendas.

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

Correto

Um track com kind="captions" fornece as legendas em inglês para o mesmo vídeo.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/mouse-events-have-key-events

Exigir eventos de foco e perda de foco junto aos eventos de mouse

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

A visibilidade da prévia muda apenas por meio dos manipuladores de entrada e saída do mouse.

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

Correto

As mesmas ações da prévia são executadas ao receber e perder o foco, e o botão pode receber foco pelo teclado.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-access-key

Proibir o uso do atributo accesskey

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O atalho accesskey="s" pode entrar em conflito com atalhos do navegador ou de tecnologias assistivas.

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

Correto

Remover accesskey mantém disponível o botão Save comum.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-aria-hidden-on-focusable

Proibir aria-hidden="true" em elementos que podem receber foco

Incorreto · Correto

Severidade padrão: error
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O botão Close, que pode receber foco, é ocultado da árvore de acessibilidade com aria-hidden="true".

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

Correto

O botão permanece exposto e recebe um rótulo Close, em vez de ser ocultado.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-autofocus

Proibir o uso do atributo autofocus

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

O campo solicita foco automático quando aparece.

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

Correto

Remover autofocus evita essa solicitação de foco automático e mantém o campo de consulta.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-distracting-elements

Proibir elementos que causam distração, como <marquee> e <blink>

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O elemento marquee introduz texto que se move automaticamente.

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

Correto

Um parágrafo exibe a mesma oferta sem o elemento marquee que causa distração.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-i-for-icon

Proibir o uso do elemento <i> para ícones

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O ícone é renderizado por meio de i, cuja semântica de texto não descreve uma ação representada apenas por um ícone.

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

Correto

Um span decorativo oculta o glifo do ícone, enquanto o texto separado Delete item dá um nome à ação do botão.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-redundant-roles

Proibir papéis ARIA redundantes

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Disponível para os diagnósticos compatíveis
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O botão nativo já tem o papel de botão, então role="button" repete sua semântica implícita.

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

Correto

Remover o papel repetido mantém a semântica de botão fornecida pelo HTML.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

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

Proibir referências a IDs inexistentes

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

aria-labelledby aponta para save-label, mas nenhum elemento declara esse ID.

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

Correto

Adicionar o span correspondente resolve a referência e fornece o rótulo do botão.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-role-presentation-on-focusable

Proibir role="presentation" ou role="none" em elementos que podem receber foco

Incorreto · Correto

Severidade padrão: error
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O link de cobrança, que pode receber foco, solicita role=presentation, o que entra em conflito com seu papel interativo de link; os navegadores devem ignorar essa solicitação de apresentação.

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

Correto

Remova a solicitação de apresentação conflitante e use o papel nativo de link e o destino de cobrança.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/no-static-element-interactions

Proibir manipuladores de eventos em elementos estáticos

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

Uma seção estática recebe uma ação da tecla Enter sem ter um papel interativo.

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

Correto

Um botão nativo executa a mesma ação usando um elemento interativo adequado.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/placeholder-label-option

Exigir uma opção de orientação em um select required

Incorreto · Correto

Severidade padrão: warning
Predefinições: nuxt, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O select é required, mas a primeira opção é Japão, então o formulário começa com um país já escolhido e required nunca bloqueia o envio.

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

Correto

Uma primeira opção vazia é a orientação: o select começa sem valor, e required obriga a escolher um país.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/role-has-required-aria-props

Exigir as propriedades obrigatórias dos papéis ARIA

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O papel de caixa de seleção omite aria-checked, que informa o estado da caixa de seleção.

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

Correto

aria-checked="false" fornece o estado exigido pelo papel de caixa de seleção.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/tabindex-no-positive

Proibir valores positivos de tabindex

Incorreto · Correto

Severidade padrão: warning
Predefinições: happy-path, nuxt, ecosystem, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

Um tabindex positivo de 3 cria uma ordem de foco personalizada antes dos controles comuns.

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

Correto

O botão usa sua ordem de foco nativa sem um tabindex positivo.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

a11y/use-list

Sugerir elementos de lista para textos que parecem itens de lista

Incorreto · Correto

Severidade padrão: warning
Predefinições: nuxt, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (Vite+)

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

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

Incorreto

Os itens das tarefas são parágrafos separados com marcadores de hífen digitados, em vez de elementos de lista.

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

Correto

Uma lista não ordenada e seus itens expressam as mesmas tarefas com semântica de lista.

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras

vue/use-unique-element-ids

Exigir IDs de elementos únicos por meio de useId(), em vez de literais estáticos

Incorreto · Correto

Severidade padrão: warning
Predefinições: nuxt, opinionated
Correção automática: Nenhuma; revise a alteração sugerida
Aplicável a: Templates e blocos de SFC Vue, com o contexto do script quando exigido pela regra
Opções: Sem opções específicas da regra. A severidade e a seleção de predefinições são configuráveis.

Configuração (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

Incorreto

O ID literal email é reutilizado por todas as instâncias deste componente, o que pode direcionar seu rótulo ao elemento errado quando várias instâncias são renderizadas.

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

Correto

useId() produz o emailId da instância; vincule o mesmo valor ao for do rótulo e ao id do input.

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

const emailId = useId();
</script>

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

O exemplo correto evita o diagnóstico desta regra com a configuração acima; outras regras ainda podem emitir diagnósticos.

Implementação · Todas as regras