Sobre este problema HTML
A especificação WAI-ARIA define um modelo de propriedade rigoroso para roles relacionados com separadores. Um elemento com role="tab" controla a visibilidade de um elemento role="tabpanel" associado, e os separadores devem estar agrupados dentro de um tablist. Esta relação é como as tecnologias assistivas, como leitores de ecrã, compreendem e comunicam o padrão de interface de separadores aos utilizadores — por exemplo, anunciando “separador 2 de 4” quando o foco se move entre separadores.
Quando um tab não está contido ou não é propriedade de um tablist, os leitores de ecrã não conseguem determinar quantos separadores existem no grupo, qual separador está atualmente selecionado, ou como navegar entre eles. Isto quebra fundamentalmente a acessibilidade da interface de separadores, tornando-a confusa ou inutilizável para pessoas que dependem de tecnologias assistivas.
Existem duas maneiras de estabelecer a relação necessária:
-
Contenção direta: Coloque os elementos
role="tab"como filhos diretos do elementorole="tablist". Esta é a abordagem mais comum e direta. -
Usando
aria-owns: Se a estrutura DOM impede o aninhamento direto, adicionearia-ownsao elementotablistcom uma lista de valoresidseparados por espaços que referenciam cada separador. Isto diz às tecnologias assistivas que otablistpossui esses separadores mesmo que não sejam filhos diretos no DOM.
Exemplos
Incorreto: separador fora de um tablist
Neste exemplo, os botões role="tab" são irmãos do tablist em vez de filhos dele, o que desencadeia o erro de validação.
<div class="tabs">
<div role="tablist" aria-label="Sample Tabs"></div>
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
First Tab
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">
Second Tab
</button>
</div>
Correto: separadores como filhos diretos do tablist
A correção mais simples é colocar os elementos role="tab" diretamente dentro do elemento role="tablist".
<div class="tabs">
<div role="tablist" aria-label="Sample Tabs">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
First Tab
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
Second Tab
</button>
</div>
<div id="panel-1" role="tabpanel" tabindex="0" aria-labelledby="tab-1">
<p>Content for the first panel</p>
</div>
<div id="panel-2" role="tabpanel" tabindex="0" aria-labelledby="tab-2" hidden>
<p>Content for the second panel</p>
</div>
</div>
Correto: usando aria-owns quando o aninhamento DOM não é possível
Se o seu layout ou framework torna difícil aninhar os separadores diretamente dentro do tablist, pode usar aria-owns para estabelecer a relação programaticamente.
<div class="tabs">
<div role="tablist" aria-label="Sample Tabs" aria-owns="tab-1 tab-2"></div>
<div class="tab-wrapper">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
First Tab
</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
Second Tab
</button>
</div>
<div id="panel-1" role="tabpanel" tabindex="0" aria-labelledby="tab-1">
<p>Content for the first panel</p>
</div>
<div id="panel-2" role="tabpanel" tabindex="0" aria-labelledby="tab-2" hidden>
<p>Content for the second panel</p>
</div>
</div>
Notas adicionais
-
Cada elemento
role="tab"deve usararia-selectedpara indicar qual separador está ativo ("true") e quais não estão ("false"). -
Use
aria-controlsem cada separador para referenciar oiddo seutabpanelassociado. -
Use
aria-labelledbyem cadatabpanelpara apontar de volta para o seu separador controlador. -
Defina
tabindex="0"no separador ativo etabindex="-1"nos separadores inativos para suportar navegação por teclado com teclas de seta dentro dotablist. -
Inclua sempre um
aria-labelouaria-labelledbynotablistpara lhe dar um nome acessível.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.
Saiba mais: