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:
-
Remover
aria-hidden="true"de elementos que contêm filhos focalizáveis, se esses filhos precisam de ser interativos. -
Remover elementos focalizáveis de dentro do contentor com
aria-hidden="true"se toda a secção é realmente destinada a estar escondida. -
Tornar elementos focalizáveis não focalizáveis adicionando
tabindex="-1"a ligações, botões, ou outros elementos interativos dentro do contentor escondido. -
Usar o atributo
disabledem controlos de formulário (nãoaria-disabled, que não previne efetivamente o foco). -
Esconder elementos com CSS usando
display: noneouvisibility: 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
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.