Sobre este problema HTML
O elemento <a> é um elemento de conteúdo interativo — já é focalizável e navegável por teclado por defeito. Quando coloca um elemento com atributo tabindex dentro de um link, cria um alvo de foco aninhado. Isto significa que utilizadores de teclado e leitores de ecrã encontram dois (ou mais) itens focalizáveis onde apenas um é esperado. O navegador pode não lidar com isto de forma consistente, e a experiência do utilizador torna-se imprevisível: ao pressionar Enter deve ativar o link ou o elemento focalizável interno?
A especificação HTML define que certos elementos interativos não devem ser aninhados dentro de outros elementos interativos. O modelo de conteúdo de um elemento <a> proíbe explicitamente conteúdo interativo como descendentes. Adicionar tabindex a qualquer elemento torna-o interativo (focalizável), o que viola esta regra.
Isto é importante por várias razões:
- Acessibilidade: Os leitores de ecrã podem anunciar elementos focalizáveis aninhados de forma confusa, ou ignorá-los completamente. Os utilizadores que dependem da navegação por teclado podem ficar presos ou confundidos por paragens de tab inesperadas dentro de um link.
- Conformidade com normas: O validador W3C sinaliza isto como um erro porque viola o modelo de conteúdo HTML para elementos âncora.
- Inconsistência entre navegadores: Diferentes navegadores podem lidar com elementos focalizáveis aninhados de forma diferente, levando a comportamento imprevisível entre plataformas.
Para corrigir esta questão, tem algumas opções:
-
Remover o atributo
tabindexdo elemento descendente se não precisar de ser independentemente focalizável. -
Reestruturar a sua marcação para que o elemento focalizável seja um irmão do elemento
<a>em vez de um descendente. - Repensar o design — se precisar de múltiplos alvos interativos na mesma área, considere usar elementos separados estilizados para aparecerem como uma única unidade.
Exemplos
❌ Inválido: Elemento com tabindex dentro de um elemento <a>
<a href="/products">
<div tabindex="0">
<h2>Our Products</h2>
<p>Browse our full catalog</p>
</div>
</a>
O <div> tem tabindex="0", tornando-o focalizável dentro de um elemento <a> já focalizável. Isto cria alvos de foco conflituantes.
✅ Corrigido: Remover tabindex do descendente
<a href="/products">
<div>
<h2>Our Products</h2>
<p>Browse our full catalog</p>
</div>
</a>
Como o elemento <a> já é focalizável e clicável, o <div> interno não precisa do seu próprio tabindex. Removê-lo resolve o conflito.
❌ Inválido: span com tabindex dentro de um link
<a href="/profile">
<span tabindex="-1">User Name</span>
</a>
Mesmo tabindex="-1" (que remove o elemento da ordem natural de tab mas ainda o torna programaticamente focalizável) desencadeia este erro de validação quando usado dentro de um elemento <a>.
✅ Corrigido: Remover tabindex do span
<a href="/profile">
<span>User Name</span>
</a>
❌ Inválido: Elemento tipo botão aninhado dentro de um link
<a href="/dashboard">
<div tabindex="0" role="button">Settings</div>
</a>
✅ Corrigido: Separar os elementos interativos
<div class="card-actions">
<a href="/dashboard">Dashboard</a>
<button type="button">Settings</button>
</div>
Se realmente precisar de dois elementos interativos distintos, coloque-os como irmãos em vez de aninhar um dentro do outro. Use CSS para estilizá-los como uma unidade visual coesa se necessário.
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: