Sobre este problema HTML
A especificação HTML define o modelo de conteúdo do elemento <button> como “conteúdo de frase” mas exclui explicitamente conteúdo interativo. Uma vez que o elemento <a> (quando tem um atributo href) é classificado como conteúdo interativo, aninhá-lo dentro de um <button> viola esta regra. A mesma restrição aplica-se a qualquer elemento que tenha role="button", pois funciona semanticamente como um botão.
Isto é problemático por várias razões:
- Acessibilidade: Os leitores de ecrã e as tecnologias assistivas não conseguem transmitir de forma fiável o propósito de elementos interativos aninhados. Um utilizador que navegue pela página usando a tecla Tab pode encontrar alvos de foco confusos ou duplicados, e a ação pretendida torna-se ambígua.
- Comportamento imprevisível: Os navegadores lidam com elementos interativos aninhados de forma inconsistente. Clicar no link dentro de um botão pode desencadear o manipulador de clique do botão, a navegação do link, ambos, ou nenhum — dependendo do navegador.
- Conformidade com as normas: A especificação HTML proíbe este aninhamento para garantir um modelo de interação claro e inequívoco para todos os utilizadores e agentes de utilizador.
Para corrigir isto, decida o que o elemento deve fazer. Se navegar para um URL, use um elemento <a> (estilizado como um botão se necessário). Se executar uma ação como submeter um formulário ou alternar algo, use um <button>. Se precisar de ambos os comportamentos, gira a navegação programaticamente via JavaScript num <button>, ou separe-os em dois elementos distintos.
Exemplos
❌ Incorreto: link aninhado dentro de um botão
<button>
<a href="/dashboard">Ir para o Dashboard</a>
</button>
❌ Incorreto: link dentro de um elemento com role="button"
<div role="button">
<a href="/settings">Definições</a>
</div>
✅ Correto: usar uma âncora estilizada como um botão
Se o objetivo é a navegação, use um elemento <a> e estilize-o para parecer um botão com CSS:
<a href="/dashboard" class="button">Ir para o Dashboard</a>
.button {
display: inline-block;
padding: 8px 16px;
background-color: #007bff;
color: #fff;
text-decoration: none;
border-radius: 4px;
cursor: pointer;
}
✅ Correto: usar um botão com navegação JavaScript
Se precisar de semânticas de botão mas também quiser navegar, gira a navegação em JavaScript:
<button type="button" onclick="location.href='/dashboard'">
Ir para o Dashboard
</button>
✅ Correto: separar os dois elementos
Se tanto uma ação de botão como um link forem genuinamente necessários, coloque-os lado a lado:
<button type="button">Guardar</button>
<a href="/dashboard">Ir para o Dashboard</a>
✅ Correto: link sem href dentro de um botão (caso limite)
Um elemento <a> sem um atributo href não é conteúdo interativo, pelo que é tecnicamente válido dentro de um <button>. No entanto, isto raramente é útil na prática:
<button type="button">
<a>Texto da etiqueta</a>
</button>
Como regra geral, nunca aninhe um elemento clicável dentro de outro. Isto aplica-se não apenas a <a> dentro de <button>, mas também a outras combinações como <button> dentro de <a>, ou <a> dentro de <a>. Manter elementos interativos separados garante um comportamento previsível e uma boa experiência para todos os utilizadores.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.