Sobre esta regra de acessibilidade
Porque é que isto é um problema de acessibilidade
Em HTML, o atributo id é concebido para ser um identificador único para um único elemento no documento. Quando dois ou mais elementos partilham o mesmo id, o navegador não tem uma forma fiável de determinar qual elemento está a ser referenciado. Isto torna-se numa barreira crítica de acessibilidade quando esse id é usado para criar relações entre elementos — como ligar uma <label> a um campo de formulário, ou conectar uma descrição a um widget através de aria-describedby.
As tecnologias assistivas como leitores de ecrã dependem dessas relações baseadas em id para comunicar informação aos utilizadores. Quando existem duplicados, o leitor de ecrã normalmente resolve a referência para o primeiro elemento no DOM com esse id, que pode não ser o alvo pretendido. Isto significa:
- Um utilizador cego ou surdocego pode ouvir a etiqueta errada para um campo de formulário, ou nenhuma etiqueta de todo.
-
Uma relação ARIA como
aria-labelledbyouaria-describedbypode apontar para o conteúdo errado, dando aos utilizadores contexto incorreto ou em falta. -
Componentes interativos que dependem de
aria-owns,aria-controlsouaria-activedescendantpodem quebrar completamente.
Esta regra relaciona-se com o Critério de Sucesso WCAG 4.1.2: Nome, Função, Valor (Nível A), que requer que todos os componentes da interface do utilizador tenham nomes acessíveis e funções que possam ser determinados programaticamente. Valores de id duplicados usados em ARIA ou associações de etiquetas minam diretamente este requisito ao criar relações programáticas ambíguas ou quebradas.
Como corrigir
-
Identifique todos os valores de
idduplicados que são referenciados por atributos ARIA (aria-labelledby,aria-describedby,aria-controls,aria-owns,aria-activedescendant, etc.) ou pelo atributoforde um elemento<label>. -
Renomeie os valores de
idduplicados para que cada um seja único dentro do documento. -
Atualize quaisquer referências a esses valores de
idem atributos ARIA ou atributosforpara corresponder aos novos valores únicos. - Verifique que cada relação ainda funciona corretamente testando com um leitor de ecrã ou o verificador de acessibilidade axe.
Exemplos
Incorreto: id duplicado em elementos referenciados por for
Neste exemplo, dois inputs partilham o mesmo id de "email". A segunda <label> pretende referenciar o segundo input, mas ambos os atributos for resolvem para o primeiro input.
<label for="email">Email Pessoal</label>
<input type="email" id="email">
<label for="email">Email de Trabalho</label>
<input type="email" id="email">
Um utilizador de leitor de ecrã ao navegar para o segundo input não ouviria nenhuma etiqueta ou a etiqueta errada, tornando impossível saber que informação inserir.
Correto: valores de id únicos para cada input
<label for="personal-email">Email Pessoal</label>
<input type="email" id="personal-email">
<label for="work-email">Email de Trabalho</label>
<input type="email" id="work-email">
Incorreto: id duplicado referenciado por aria-labelledby
<span id="section-title">Endereço de Envio</span>
<div role="group" aria-labelledby="section-title">
<!-- campos de envio -->
</div>
<span id="section-title">Endereço de Faturação</span>
<div role="group" aria-labelledby="section-title">
<!-- campos de faturação -->
</div>
Ambos os grupos seriam anunciados como “Endereço de Envio” porque o navegador resolve ambas as referências aria-labelledby para o primeiro <span> com id="section-title".
Correto: valores de id únicos para cada elemento referenciado
<span id="shipping-title">Endereço de Envio</span>
<div role="group" aria-labelledby="shipping-title">
<!-- campos de envio -->
</div>
<span id="billing-title">Endereço de Faturação</span>
<div role="group" aria-labelledby="billing-title">
<!-- campos de faturação -->
</div>
Incorreto: id duplicado usado em aria-describedby
<p id="hint">Deve ter pelo menos 8 caracteres.</p>
<label for="password">Palavra-passe</label>
<input type="password" id="password" aria-describedby="hint">
<p id="hint">Reintroduza a sua palavra-passe para confirmar.</p>
<label for="confirm-password">Confirmar Palavra-passe</label>
<input type="password" id="confirm-password" aria-describedby="hint">
Correto: valores de id únicos para cada descrição
<p id="password-hint">Deve ter pelo menos 8 caracteres.</p>
<label for="password">Palavra-passe</label>
<input type="password" id="password" aria-describedby="password-hint">
<p id="confirm-hint">Reintroduza a sua palavra-passe para confirmar.</p>
<label for="confirm-password">Confirmar Palavra-passe</label>
<input type="password" id="confirm-password" aria-describedby="confirm-hint">
Ajude-nos a melhorar os nossos guias
Detecte problemas de acessibilidade automaticamente
O Rocket Validator examina milhares de páginas com Axe Core e o W3C Validator, encontrando problemas de acessibilidade em todo o seu site.