Skip to main content

Sobre esta regra de acessibilidade

O atributo aria-hidden="true" instrui as tecnologias de apoio a ignorarem um elemento e todos os seus descendentes. Isto é útil para esconder conteúdo puramente decorativo — como fontes de ícones ou elementos visuais redundantes — que iriam sobrecarregar a experiência do leitor de ecrã. No entanto, surge um problema sério quando elementos focalizáveis como ligações, botões, campos de formulário, ou elementos com tabindex="0" existem dentro de um contentor com aria-hidden="true".

Quando isto acontece, os utilizadores de teclado ainda podem usar Tab para chegar a esses elementos, mas os leitores de ecrã não os irão anunciar. O utilizador para no que parece ser um controlo invisível e sem etiqueta. Não têm forma de saber o que é o elemento ou o que faz. Isto afeta utilizadores cegos, utilizadores surdocegos, utilizadores com baixa visão que dependem de leitores de ecrã, e utilizadores com deficiências motoras que navegam exclusivamente por teclado.

É também importante compreender que aria-hidden="false" num descendente não substitui aria-hidden="true" num antepassado. Uma vez que um elemento pai está escondido da árvore de acessibilidade, todos os filhos permanecem escondidos independentemente do seu próprio valor aria-hidden. Quaisquer filhos focalizáveis dentro dessa subárvore ainda criam o mesmo problema.

Critérios de Sucesso WCAG Relacionados

Esta regra relaciona-se principalmente com o Critério de Sucesso WCAG 4.1.2: Nome, Função, Valor (Nível A). Este critério exige que para todos os componentes de interface do utilizador, o nome e a função possam ser determinados programaticamente, e estados, propriedades e valores possam ser definidos programaticamente. Um elemento focalizável dentro de um contentor com aria-hidden="true" viola isto porque o seu nome e função são removidos da API de acessibilidade enquanto permanece acessível via teclado — tornando impossível para as tecnologias de apoio transmitirem o seu propósito. Esta regra é sinalizada nas WCAG 2.0, 2.1, e 2.2 no Nível A, bem como nas diretrizes Trusted Tester, EN 301 549, e RGAA.

Como Corrigir

Existem várias estratégias para resolver esta questão:

  1. Remover aria-hidden="true" de elementos que contêm filhos focalizáveis, se esses filhos precisam de ser interativos.
  2. Remover elementos focalizáveis de dentro do contentor com aria-hidden="true" se toda a secção é realmente destinada a estar escondida.
  3. Tornar elementos focalizáveis não focalizáveis adicionando tabindex="-1" a ligações, botões, ou outros elementos interativos dentro do contentor escondido.
  4. Usar o atributo disabled em controlos de formulário (não aria-disabled, que não previne efetivamente o foco).
  5. Esconder elementos com CSS usando display: none ou visibility: hidden, que os remove tanto da árvore de acessibilidade como da ordem de foco simultaneamente.

Se precisar de esconder conteúdo das tecnologias de apoio, certifique-se de que o significado e funcionalidade equivalentes ainda estão disponíveis através de outros meios acessíveis.

Exemplos

Incorreto: Ligação focalizável dentro de aria-hidden="true"

A ligação é removida da árvore de acessibilidade mas ainda recebe foco do teclado.

<div aria-hidden="true">
  <a href="/home">Home</a>
</div>

Incorreto: Ligação focalizável fora do ecrã dentro de aria-hidden="true"

Mover uma ligação para fora do ecrã não a remove da ordem de foco.

<div aria-hidden="true">
  <a href="/" style="position:absolute; top:-999em">Link</a>
</div>

Incorreto: Usar aria-disabled em vez de disabled

O atributo aria-disabled não previne efetivamente que o campo receba foco.

<div aria-hidden="true">
  <input aria-disabled="true" />
</div>

Incorreto: Elemento com tabindex="0" e aria-hidden="true"

Adicionar tabindex="0" torna um elemento normalmente não focalizável em focalizável, criando um conflito com aria-hidden="true".

<p tabindex="0" aria-hidden="true">Algum texto descritivo</p>

Incorreto: Tentar substituir aria-hidden num descendente

Definir aria-hidden="false" num filho não o reexpõe quando um pai tem aria-hidden="true". O botão permanece escondido das tecnologias de apoio mas ainda recebe foco.

<div aria-hidden="true">
  <div aria-hidden="false">
    <button>Submeter</button>
  </div>
</div>

Incorreto: <summary> focalizável dentro de aria-hidden="true"

O elemento <summary> é nativamente focalizável.

<details aria-hidden="true">
  <summary>Mais informações</summary>
  <p>Detalhes adicionais aqui.</p>
</details>

Correto: Conteúdo não focalizável dentro de aria-hidden="true"

Um parágrafo sem elementos interativos é seguro de esconder.

<p aria-hidden="true">Texto descritivo decorativo</p>

Correto: Elementos focalizáveis escondidos com CSS display: none

Usar display: none remove a ligação tanto da ordem de foco como da árvore de acessibilidade.

<div aria-hidden="true">
  <a href="/" style="display:none">Link</a>
</div>

Correto: Elementos focalizáveis tornados não focalizáveis com tabindex="-1"

Adicionar tabindex="-1" remove o botão da ordem de tabulação.

<div aria-hidden="true">
  <button tabindex="-1">Fechar</button>
</div>

Correto: Campo de formulário adequadamente desativado com o atributo disabled

O atributo disabled previne que o campo receba foco totalmente.

<input disabled aria-hidden="true" />

Correto: Remover aria-hidden e manter elementos interativos

Se o conteúdo precisa de ser focalizável, simplesmente não o esconda das tecnologias de apoio.

<div>
  <a href="/home">Home</a>
</div>

Ajude-nos a melhorar os nossos guias

Este guia foi útil?

Detecte problemas de acessibilidade automaticamente

O Rocket Validator examina milhares de páginas com Axe Core e o W3C Validator, encontrando problemas de acessibilidade em todo o seu site.

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