Sobre este problema HTML
A especificação HTML define <label> como um elemento cujo modelo de conteúdo permite conteúdo de fraseamento mas exclui explicitamente outros elementos <label>. Quando você aninha um <label> dentro de outro, os browsers não conseguem determinar qual controlo de formulário cada label deve descrever. Isto quebra o propósito fundamental do elemento <label>—fornecer uma associação clara, um para um, entre uma descrição de texto e o seu controlo de formulário correspondente.
Esta questão importa por várias razões:
-
Acessibilidade: Os leitores de ecrã dependem do elemento
<label>para anunciar o propósito dos controlos de formulário. Labels aninhados criam confusão sobre qual texto de label pertence a qual input, tornando os formulários difíceis ou impossíveis de navegar para utilizadores de tecnologia assistiva. -
Usabilidade: Clicar num
<label>deve focar ou ativar o seu controlo associado. Labels aninhados criam alvos de clique sobrepostos com comportamento imprevisível. -
Conformidade com normas: A norma HTML living standard do WHATWG afirma explicitamente que elementos
<label>não devem ser aninhados, e os validadores irão sinalizar isto como um erro.
Este erro ocorre frequentemente em algumas situações: duplicação acidental de tags de fecho, envolver um grupo complexo de formulário num <label> quando um <fieldset> seria mais apropriado, ou usar um sistema de templates que inadvertidamente produz labels aninhados.
Exemplos
❌ Labels aninhados (inválido)
<label>
Nome Completo
<label>
Primeiro Nome
<input type="text" name="first-name">
</label>
</label>
❌ Tag de fecho extra causando um problema de parser
Uma tag de fecho </label> perdida pode por vezes fazer com que a recuperação de erros do browser produza aninhamento inesperado:
<label>Name</label></label>
<label for="email">Email</label>
Embora o </label> extra seja o problema raiz aqui, alguns parsers e validadores podem interpretar isto como um problema de aninhamento. Certifique-se sempre de que as suas tags de abertura e fecho estão corretamente emparelhadas.
✅ Labels separados para inputs separados
<label for="first-name">Primeiro Nome</label>
<input type="text" id="first-name" name="first-name">
<label for="last-name">Último Nome</label>
<input type="text" id="last-name" name="last-name">
✅ Usar associação de label implícita (um label por input)
<label>
Primeiro Nome
<input type="text" name="first-name">
</label>
<label>
Último Nome
<input type="text" name="last-name">
</label>
✅ Agrupar controlos relacionados com <fieldset> em vez de aninhar labels
Se precisar de agrupar múltiplos inputs rotulados sob um cabeçalho partilhado, use um <fieldset> com um <legend> em vez de envolver labels dentro de um label:
<fieldset>
<legend>Nome Completo</legend>
<label for="first-name">Primeiro Nome</label>
<input type="text" id="first-name" name="first-name">
<label for="last-name">Último Nome</label>
<input type="text" id="last-name" name="last-name">
</fieldset>
Esta abordagem fornece a semântica de agrupamento que você precisa enquanto mantém cada <label> corretamente associado a um único controlo de formulário. O <legend> serve como a descrição ao nível do grupo, e cada <label> descreve o seu input individual—dando tanto aos utilizadores visuais como aos utilizadores de tecnologia assistiva uma compreensão clara da estrutura do formulário.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.