Sobre esta regra de acessibilidade
A especificação WAI-ARIA define uma hierarquia rigorosa para muitas funções. Algumas funções só são significativas quando aparecem como filhos de funções pai específicas. Por exemplo, um tab deve ser possuído por um tablist, um listitem deve ser possuído por um list ou group, e um menuitem deve ser possuído por um menu ou menubar. Quando estas relações pai-filho estão em falta, a função torna-se semanticamente órfã — tecnologias assistivas como leitores de ecrã não conseguem comunicar o contexto, posição ou propósito do elemento ao utilizador.
Porque isto é importante
Esta regra relaciona-se com o Critério de Sucesso 1.3.1 das WCAG 2.0/2.1/2.2: Informação e Relações (Nível A), que requer que informação, estrutura e relações transmitidas visualmente estejam também disponíveis programaticamente. Quando uma função ARIA carece do seu pai obrigatório, a relação estrutural é perdida na árvore de acessibilidade.
Os utilizadores mais afetados incluem:
- Utilizadores cegos e surdocegos que dependem de leitores de ecrã. Sem a função pai correta, os leitores de ecrã não conseguem anunciar contexto como “item 3 de 5 numa lista” ou “separador 2 de 4.”
- Utilizadores com deficiências motoras que dependem de tecnologia assistiva para navegação. Funções pai em falta podem quebrar padrões de interação de teclado esperados para widgets compostos como menus, tablists e árvores.
O impacto no utilizador é crítico — uma função órfã pode tornar um widget inteiro inutilizável para utilizadores de tecnologia assistiva.
Funções pai obrigatórias comuns
Aqui estão algumas funções frequentemente usadas e os seus pais obrigatórios:
| Função Filha | Função(ões) Pai Obrigatória(s) |
|---|---|
listitem |
list ou group |
tab |
tablist |
tabpanel |
(associado através do padrão tablist) |
menuitem, menuitemcheckbox, menuitemradio |
menu, menubar, ou group |
treeitem |
tree ou group |
row |
table, grid, rowgroup, ou treegrid |
cell, gridcell |
row |
columnheader, rowheader |
row |
option |
listbox ou group |
Como corrigir o problema
-
Envolva o elemento na sua função pai obrigatória. A correção mais simples é garantir que a estrutura DOM reflete a hierarquia obrigatória. Coloque o elemento dentro de um contentor que tenha a função pai correta.
-
Use
aria-ownsquando a estrutura DOM não coincide. Se o elemento filho não pode ser um descendente DOM do pai (por exemplo, devido a restrições de layout), pode usararia-ownsno elemento pai para estabelecer a relação programaticamente. O atributoaria-ownsdiz às tecnologias assistivas que o elemento referenciado deve ser tratado como um filho, independentemente da posição DOM. -
Verifique a especificação WAI-ARIA para a função específica que está a usar para confirmar que funções pai são obrigatórias.
Exemplos
Incorreto: listitem sem um pai list
A função listitem requer um pai com role="list" ou role="group", mas aqui situa-se diretamente dentro de uma div simples:
<div>
<div role="listitem">Apples</div>
<div role="listitem">Bananas</div>
<div role="listitem">Cherries</div>
</div>
Correto: listitem dentro de um pai list
<div role="list">
<div role="listitem">Apples</div>
<div role="listitem">Bananas</div>
<div role="listitem">Cherries</div>
</div>
Incorreto: tab sem um pai tablist
<div>
<button role="tab" aria-selected="true">Tab 1</button>
<button role="tab" aria-selected="false">Tab 2</button>
</div>
Correto: tab dentro de um pai tablist
<div role="tablist">
<button role="tab" aria-selected="true">Tab 1</button>
<button role="tab" aria-selected="false">Tab 2</button>
</div>
Correto: usar aria-owns quando a estrutura DOM difere
Quando restrições de layout impedem aninhar o filho dentro do pai no DOM, use aria-owns para estabelecer a relação:
<div role="tablist" aria-owns="tab1 tab2">
<!-- Os separadores estão noutro local no DOM devido a necessidades de layout -->
</div>
<div id="tab1" role="tab" aria-selected="true">Tab 1</div>
<div id="tab2" role="tab" aria-selected="false">Tab 2</div>
Incorreto: menuitem fora de um menu
<div>
<button role="menuitem">Cut</button>
<button role="menuitem">Copy</button>
<button role="menuitem">Paste</button>
</div>
Correto: menuitem dentro de um menu
<div role="menu">
<button role="menuitem">Cut</button>
<button role="menuitem">Copy</button>
<button role="menuitem">Paste</button>
</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.