Sobre este problema HTML
Unicode permite que alguns caracteres sejam representados de múltiplas formas. Por exemplo, a letra acentuada “é” pode ser armazenada como um único carácter pré-composto (U+00E9) ou como dois pontos de código separados: a letra base “e” (U+0065) seguida por um acento agudo combinado (U+0301). Embora estes pareçam idênticos quando renderizados, são fundamentalmente diferentes ao nível dos bytes. A Forma de Normalização Unicode C (NFC) é a forma canónica que prefere a representação pré-composta única sempre que uma existe.
A especificação HTML e o Modelo de Caracteres W3C para a World Wide Web exigem que todo o texto em documentos HTML esteja em NFC. Isto é importante por várias razões:
- Correspondência e pesquisa de strings: Texto não-NFC pode causar falhas quando navegadores ou scripts tentam fazer correspondência de strings, comparar valores de atributos ou processar seletores CSS. Duas strings visualmente idênticas em formas de normalização diferentes não vão corresponder com comparação simples de bytes.
- Acessibilidade: Leitores de ecrã e tecnologias assistivas podem comportar-se de forma inconsistente ao encontrar sequências de caracteres decompostos.
- Interoperabilidade: Diferentes navegadores, motores de busca e ferramentas podem lidar com texto não-NFC de forma diferente, levando a comportamento imprevisível.
-
Identificadores de fragmento e IDs: Se um atributo
idcontém caracteres não-NFC, ligações de fragmento (#id) podem falhar em funcionar corretamente.
Este problema aparece mais frequentemente quando o texto é copiado de processadores de texto, PDFs ou outras aplicações que usam formas Unicode decompostas (NFD), ou quando o conteúdo é gerado por software que não normaliza a sua saída.
Como corrigir
- Identifique o texto afetado: O validador irá apontar para a linha específica que contém caracteres não-NFC. Os caracteres muitas vezes parecem normais visualmente, por isso você precisará inspecioná-los ao nível do ponto de código.
- Converta para NFC: Use um editor de texto ou ferramenta de linha de comandos que suporta normalização Unicode. Muitas linguagens de programação fornecem funções de normalização incorporadas.
- Previna problemas futuros: Configure o seu editor de texto ou pipeline de construção para guardar ficheiros em NFC. Quando aceitar input do utilizador, normalize-o no servidor antes de armazenar ou incorporar em HTML.
Em Python, pode normalizar uma string:
import unicodedata
normalized = unicodedata.normalize('NFC', original_string)
Em JavaScript (Node.js ou navegador):
const normalized = originalString.normalize('NFC');
Na linha de comandos (usando uconv do ICU):
uconv -x NFC input.html > output.html
Exemplos
Incorreto (forma decomposta — NFD)
Neste exemplo, a letra “é” é representada como dois pontos de código (e + acento agudo combinado), o que desencadeia o aviso de validação. O código fonte pode parecer idêntico à versão correta, mas os bytes subjacentes diferem:
<!-- "é" aqui é armazenado como U+0065 U+0301 (decomposto) -->
<p>Résumé available upon request.</p>
Correto (forma pré-composta — NFC)
Aqui, o mesmo texto usa o único carácter pré-composto é (U+00E9):
<!-- "é" aqui é armazenado como U+00E9 (pré-composto) -->
<p>Résumé available upon request.</p>
Incorreto em atributos
Texto não-NFC em valores de atributos também desencadeia este problema:
<!-- O id contém um carácter decomposto -->
<h2 id="resumé">Résumé</h2>
Correto em atributos
<!-- O id usa o carácter NFC pré-composto -->
<h2 id="resumé">Résumé</h2>
Embora estes exemplos pareçam iguais no texto renderizado, a diferença está em como os caracteres são codificados. Para verificar que o seu texto está em NFC, pode colá-lo numa ferramenta de inspeção Unicode ou usar as funções de normalização mencionadas acima. Para leitura adicional, o W3C fornece um excelente guia sobre Normalização em HTML e CSS.
Encontre problemas como este automaticamente
O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.
Saiba mais: