Sobre este problema HTML
O validador W3C apresenta este erro porque os roles ARIA devem ser compatíveis com o elemento ao qual são aplicados. Um elemento <ul> tem um role ARIA implícito de list, e substituí-lo por tabpanel cria um conflito. O role tabpanel sinaliza às tecnologias assistivas que o elemento é um painel de conteúdo ativado por um separador correspondente. Quando este role é colocado num <ul>, os leitores de ecrã perdem o significado semântico da lista (contagem de itens, navegação da lista, etc.) enquanto também representam incorretamente a função do elemento na interface de separadores.
Isto é importante por várias razões:
-
Acessibilidade: Os utilizadores de leitores de ecrã dependem de roles corretos para navegar e compreender a estrutura da página. Um
<ul>marcado comotabpanelconfunde tanto a sua semântica de lista como o seu papel na interface de separadores. -
Conformidade com as normas: A especificação ARIA em HTML define quais roles são permitidos em quais elementos. O role
tabpanelnão é permitido em<ul>. - Comportamento do navegador: Os navegadores podem lidar com roles conflituosos de forma inconsistente, levando a comportamentos imprevisíveis entre tecnologias assistivas.
A correção é simples: envolva o <ul> dentro de um elemento de contentor adequado (como um <div> ou <section>) e aplique o role tabpanel a esse contentor em vez disso.
Exemplos
Incorreto: role tabpanel num <ul>
Isto desencadeia o erro de validação porque tabpanel não é um role válido para <ul>:
<div role="tablist" aria-label="Recipe categories">
<button role="tab" aria-controls="panel-1" aria-selected="true" id="tab-1">Appetizers</button>
<button role="tab" aria-controls="panel-2" aria-selected="false" id="tab-2">Desserts</button>
</div>
<ul role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<li>Bruschetta</li>
<li>Spring rolls</li>
</ul>
<ul role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
<li>Tiramisu</li>
<li>Cheesecake</li>
</ul>
Correto: role tabpanel num contentor que envolve o <ul>
Mova o role tabpanel para um <div> e aninhie o <ul> dentro dele. Isto preserva tanto a semântica do painel de separadores como a semântica da lista:
<div role="tablist" aria-label="Recipe categories">
<button role="tab" aria-controls="panel-1" aria-selected="true" id="tab-1">Appetizers</button>
<button role="tab" aria-controls="panel-2" aria-selected="false" id="tab-2">Desserts</button>
</div>
<div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
<ul>
<li>Bruschetta</li>
<li>Spring rolls</li>
</ul>
</div>
<div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
<ul>
<li>Tiramisu</li>
<li>Cheesecake</li>
</ul>
</div>
Correto: usar <section> como painel de separadores
Um elemento <section> também funciona bem como contentor de painel de separadores, especialmente quando o conteúdo do painel é mais complexo:
<div role="tablist" aria-label="Project info">
<button role="tab" aria-controls="tasks-panel" aria-selected="true" id="tasks-tab">Tasks</button>
<button role="tab" aria-controls="notes-panel" aria-selected="false" id="notes-tab">Notes</button>
</div>
<section role="tabpanel" id="tasks-panel" aria-labelledby="tasks-tab">
<h2>Current tasks</h2>
<ul>
<li>Review pull requests</li>
<li>Update documentation</li>
</ul>
</section>
<section role="tabpanel" id="notes-panel" aria-labelledby="notes-tab" hidden>
<h2>Meeting notes</h2>
<p>Discussed project timeline and milestones.</p>
</section>
Numa interface com separadores devidamente estruturada:
-
O role
tablistvai no contentor que contém os botões de separadores. -
Cada gatilho de separador recebe
role="tab"comaria-controlsa apontar para oiddo seu painel. -
Cada painel de conteúdo recebe
role="tabpanel"num contentor genérico como<div>ou<section>, comaria-labelledbya referenciar oiddo separador correspondente. -
Elementos de lista como
<ul>e<ol>devem permanecer dentro do painel como conteúdo regular, mantendo a sua semântica nativa de lista.
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: