Sobre este problema HTML
O elemento label associa uma legenda a um controlo de formulário. Existem duas formas de criar esta associação:
-
Associação implícita — Colocar o controlo de formulário diretamente dentro do elemento
label. Não são necessários atributosforouid. -
Associação explícita — Usar o atributo
fornolabel, definindo o seu valor para oiddo controlo de formulário associado.
Ambos os métodos funcionam de forma independente. O problema surge quando os mistura incorretamente — aninhando um select dentro de um label que tem um atributo for, mas o select não tem id ou tem um id que não corresponde ao valor for. Nesta situação, a associação explícita (via for) aponta para nada ou para o elemento errado, enquanto a associação implícita (via aninhamento) ainda existe. Este estado contraditório viola a especificação HTML e pode fazer com que as tecnologias assistivas como leitores de ecrã identifiquem incorretamente ou ignorem o rótulo, reduzindo a acessibilidade para utilizadores que dependem delas.
A especificação HTML do WHATWG exige que quando um atributo for está presente num label, deve referenciar um elemento rotulável válido por id. Se o controlo de formulário já está aninhado dentro do label, o atributo for é redundante — mas se estiver presente, ainda deve referenciar corretamente esse controlo.
Como corrigir
Tem duas opções:
-
Remover o atributo
for— Se oselectjá está dentro dolabel, a associação implícita trata de tudo. Esta é a correção mais simples. -
Adicionar ou corrigir o
id— Manter o atributoformas garantir que oselecttem umidcorrespondente.
Exemplos
❌ Incorreto: atributo for sem id correspondente
O atributo for referencia "age", mas o select não tem id nenhum:
<label for="age">
Age
<select>
<option>Young</option>
<option>Old</option>
</select>
</label>
❌ Incorreto: atributo for com id não correspondente
O atributo for referencia "age", mas o select tem um id diferente:
<label for="age">
Age
<select id="age-select">
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Opção de correção 1: remover o atributo for (associação implícita)
Uma vez que o select está aninhado dentro do label, a associação implícita é suficiente:
<label>
Age
<select>
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Opção de correção 2: corresponder o atributo for com o id (associação explícita)
Manter o atributo for e dar ao select um id correspondente:
<label for="age">
Age
<select id="age">
<option>Young</option>
<option>Old</option>
</select>
</label>
✅ Opção de correção 3: separar o label e o select (apenas associação explícita)
Se preferir manter o select fora do label, é necessária associação explícita com for e id correspondentes:
<label for="age">Age</label>
<select id="age">
<option>Young</option>
<option>Old</option>
</select>
Na maioria dos casos, a opção 1 (remover o atributo for) é a solução mais limpa quando o controlo já está aninhado. Use associação explícita quando o label e o controlo estão em partes separadas do DOM, como em layouts complexos de tabela ou grelha.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.