Sobre este problema HTML
Um URL pode ter apenas um identificador de fragmento — a porção que vem após o único símbolo #. Quando o browser encontra um # num URL, trata tudo depois dele como o fragmento. Se um segundo # aparecer, torna-se um carácter ilegal dentro desse fragmento porque a porção do fragmento de um URL não permite carateres # não codificados. Isto viola a especificação URL (WHATWG) e os requisitos do padrão HTML para URLs válidos no atributo href.
Isto é importante por várias razões:
- Conformidade com padrões: Os browsers podem lidar com URLs mal formados de forma inconsistente, levando a comportamento de navegação imprevisível em diferentes ambientes.
- Acessibilidade: Leitores de ecrã e tecnologias assistivas dependem de URLs bem formados para anunciar corretamente os destinos dos links e permitir que os utilizadores naveguem.
- SEO e rastreamento: Os rastreadores de motores de busca podem falhar ao seguir ou indexar páginas com URLs inválidos.
O carácter # é perfeitamente válido quando usado exatamente uma vez para introduzir um fragmento. Por exemplo, #pricing ou /faqs#pricing estão corretos. O problema surge quando um segundo # aparece, como /faqs#guarantee#pricing, ou quando # é usado numa parte do URL onde não é esperado.
Se precisar genuinamente de um carácter # literal como parte de um caminho ou string de consulta (não como um delimitador de fragmento), deve codificá-lo como %23.
Exemplos
❌ Inválido: Múltiplos carateres # no URL
Isto desencadeia o erro do validador porque o fragmento (guarantee#pricing) contém um # ilegal:
<a href="/faqs#guarantee#pricing">Garantia e Preços</a>
✅ Corrigido: Use um único identificador de fragmento
Ligue a uma secção de cada vez com um único #:
<a href="/faqs#guarantee">Garantia</a>
<a href="/faqs#pricing">Preços</a>
✅ Corrigido: Codifique o # se for um carácter literal
Se o # faz parte do caminho ou dados reais (não um delimitador de fragmento), codifique-o como %23:
<a href="/faqs%23guarantee#pricing">Preços</a>
Neste caso, /faqs%23guarantee é o caminho (contendo um # literal), e pricing é o fragmento.
Usar fragmentos corretamente numa tabela de conteúdos
Os fragmentos funcionam bem para navegação dentro da página. Cada elemento de destino precisa de um id correspondente:
<nav>
<ul>
<li><a href="#pricing">Preços</a></li>
<li><a href="#terms">Termos</a></li>
<li><a href="#guarantee">Garantia</a></li>
</ul>
</nav>
<h2 id="pricing">Preços</h2>
<p>Tudo sobre preços...</p>
<h2 id="terms">Termos</h2>
<p>Pode encontrar os nossos termos em...</p>
<h2 id="guarantee">Garantia</h2>
<p>Oferecemos uma garantia...</p>
❌ Inválido: # numa string de consulta ou caminho sem codificação
Por vezes este erro aparece quando um URL inclui acidentalmente um # não codificado no lugar errado:
<a href="/search?color=#ff0000">Itens vermelhos</a>
✅ Corrigido: Codifique o # no valor da consulta
<a href="/search?color=%23ff0000">Itens vermelhos</a>
Aqui, %23ff0000 representa corretamente a string literal #ff0000 como um valor de parâmetro de consulta, em vez de ser mal interpretado como o início de um fragmento.
Causas comuns
-
Copiar e colar URLs de outras fontes que contêm múltiplos carateres
#. - Links gerados dinamicamente onde os valores dos fragmentos não são devidamente sanitizados.
-
Códigos de cor em URLs como
#ff0000que precisam de ser codificados como%23ff0000. -
Erros de concatenação em templates onde um
#é adicionado tanto no URL base como no fragmento anexado.
A correção é sempre a mesma: certifique-se de que o seu href contém no máximo um # usado como delimitador de fragmento, e codifique (%23) qualquer # que seja um carácter literal.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.