Skip to main content
Validação HTML

Um elemento com o atributo “tabindex” não deve aparecer como descendente de um elemento com o atributo “role=button”.

Sobre este problema HTML

Quando um elemento tem role="button", as tecnologias assistivas tratam-no como um único controlo interativo — tal como um <button> nativo. Os utilizadores esperam navegar até ele uma vez, e depois ativá-lo com Enter ou Espaço. Se um descendente focalizável (um elemento com tabindex) existir dentro desse botão, cria uma segunda paragem de tabulação dentro do que deveria ser um único controlo. Isto quebra o modelo de interação esperado e confunde tanto utilizadores de teclado como leitores de ecrã.

A especificação WAI-ARIA estabelece explicitamente que certas funções, incluindo button, não devem conter descendentes interativos ou focalizáveis. Isto é porque um botão é um widget atómico — representa uma ação e deve receber foco como uma única unidade. Quando um leitor de ecrã encontra um elemento role="button", anuncia-o como um botão e espera que o utilizador interaja com ele diretamente. Um elemento focalizável aninhado perturba isto ao criar um alvo de foco ambíguo: deve o utilizador interagir com o botão exterior ou com o elemento focalizável interior?

Esta questão surge frequentemente quando os programadores envolvem elementos inline como <span> ou <a> com tabindex dentro de um <div role="button">, frequentemente para estilizar partes do botão de forma diferente ou para adicionar manipuladores de clique. A abordagem correta é garantir que apenas o elemento mais exterior semelhante a botão é focalizável.

Como corrigir

  1. Use um elemento <button> nativo. Esta é sempre a melhor solução. Botões nativos lidam com foco, interação de teclado (ativação com teclas Enter e Espaço), e anúncios de acessibilidade automaticamente — nenhum role ou tabindex necessário.

  2. Mova tabindex para o contentor role="button". Se deve usar role="button" (por exemplo, quando um <div> precisa de se comportar como um botão devido a restrições de design), coloque tabindex="0" no próprio contentor e remova tabindex de todos os descendentes.

  3. Remova tabindex dos descendentes. Se o elemento interior não precisa realmente de ser independentemente focalizável, simplesmente remova o atributo tabindex dele.

Quando usar role="button" num elemento não-interativo, lembre-se que também precisa de implementar manipuladores de eventos de teclado para Enter e Espaço para replicar completamente o comportamento de botão nativo.

Exemplos

Incorreto: descendente focalizável dentro de role="button"

<div role="button">
  <span tabindex="0">Click me</span>
</div>

O <span> com tabindex="0" cria um elemento focalizável dentro do contentor role="button", o que viola as regras de criação ARIA.

Incorreto: elemento âncora dentro de role="button"

<div role="button" tabindex="0">
  <a href="/action" tabindex="0">Perform action</a>
</div>

Mesmo que o contentor seja focalizável, o <a> aninhado com tabindex também é focalizável, criando duas paragens de tabulação para o que deveria ser um único controlo.

Correto: use um elemento <button> nativo

<button>Click me</button>

Um <button> nativo lida com foco, eventos de teclado, e semântica de acessibilidade imediatamente sem atributos adicionais.

Correto: mova tabindex para o contentor role="button"

<div role="button" tabindex="0">
  <span>Click me</span>
</div>

O tabindex="0" está no próprio elemento role="button", e o <span> interior não é independentemente focalizável.

Correto: botão nativo com conteúdo interior estilizado

<button>
  <span class="icon">★</span>
  <span class="label">Favorite</span>
</button>

Você ainda pode usar elementos interiores para fins de estilo dentro de um <button> — apenas não adicione tabindex a eles. O botão gere o foco como uma única unidade, e os leitores de ecrã anunciam o conteúdo de texto combinado.

Encontre problemas como este automaticamente

O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.

Ajude-nos a melhorar os nossos guias

Este guia foi útil?

Pronto para validar os seus sites?
Comece o seu teste gratuito hoje.