Guia prático para tornar seu site Astro compatível com WCAG AA
Índice
- Introdução
- aria-hidden em ícones decorativos
- Solução
- Notificação de leitor de tela para links externos
- Solução
- Garantia de contraste
- Problemas comuns
- Solução
- Estilos focus-visible
- Implementação com UnoCSS
- Elementos frequentemente esquecidos
- Sublinhado em links inline
- Solução
- Acessibilidade de formulários
- Validação inline
- Marcação de campos obrigatórios
- Atributo role em elementos figure
- Atributo role em elementos de lista
- Outras melhorias
- Atributos width/height em imagens
- aria-live no slider Hero
- aria-labelledby em dialog
- aria-current na paginação
- Atualização de aria-label no botão copiar
- Conclusão
- Série que inclui este artigo
Introdução
“Melhorias de acessibilidade” pode parecer algo que sempre fica para depois. No entanto, ao trabalhar nisso na prática, melhorias de contraste, operação por teclado e indicadores de foco resultam diretamente em melhor usabilidade para todos os usuários.
Neste artigo, apresentamos por categoria as melhorias realizadas para alcançar 100 pontos no Accessibility do PageSpeed em um site Astro + UnoCSS.
aria-hidden em ícones decorativos
Os ícones Iconify do UnoCSS (i-lucide-*) são frequentemente usados como decoração visual, mas quando leitores de tela os leem, notificam como “imagem” ou “imagem desconhecida”, causando confusão.
Solução
Adicione aria-hidden="true" aos ícones com propósito decorativo.
<span class="i-lucide-mail" aria-hidden="true"></span>
Contato
Essa correção foi aplicada em mais de 30 ícones em todo o site. É fácil esquecer ícones dentro de componentes como StatBar, Callout, ServiceCard e ProcessFigure, então preste atenção.
Notificação de leitor de tela para links externos
Links externos que abrem com target="_blank" são visualmente reconhecíveis como abrindo em nova aba, mas não são comunicados aos usuários de leitores de tela.
Solução
Adicione texto complementar visualmente oculto aos links externos.
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
Example
<span class="sr-only">(abre em nova aba)</span>
</a>
Usando o plugin rehype-external-links, target="_blank" e rel podem ser adicionados automaticamente aos links externos no Markdown. O texto de notificação para leitores de tela é adicionado no lado do template.
Garantia de contraste
A indicação mais comum do PageSpeed Insights é contraste insuficiente.
Problemas comuns
Usar text-slate-400 na paleta de cores do UnoCSS resulta em uma razão de contraste de aproximadamente 3:1 contra fundo branco, não atendendo ao critério WCAG AA de 4.5:1.
Solução
Alterar text-slate-400 → text-slate-500 (razão de contraste 4.6:1) resolve o critério. Como é frequentemente usado em textos auxiliares como datas e legendas, verifique em todo o site.
Estilos focus-visible
Para usuários que operam o site pelo teclado, o indicador de foco é a única pista para saber “onde estou agora”. WCAG 2.4.7 exige indicação de foco.
Implementação com UnoCSS
Configure estilos de foco comuns para botões e links. Usando a funcionalidade de atalhos do UnoCSS, uma única definição se aplica a todo o site.
shortcuts: {
'ac-btn': '... focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-2 focus-visible:outline-none',
}
focus-visible é uma pseudo-classe que não exibe o anel ao clicar com o mouse, mostrando-o apenas durante operação por teclado. A UX é melhor que focus, então use esta opção.
Elementos frequentemente esquecidos
- Botão copiar
- Botão scroll to top
- Botão fechar de anúncio âncora
- Botão fechar de modal
Sublinhado em links inline
O PageSpeed tem uma indicação de que “links são identificáveis apenas pela cor”. Isso é um problema para usuários com restrições de percepção de cores que não conseguem distinguir links.
Solução
Altere o sublinhado de apenas hover para sempre visível. Recomendamos unificar com atalhos do UnoCSS.
shortcuts: {
'ac-link': 'underline decoration-brand-300 underline-offset-2 hover:decoration-brand-500 transition-colors',
}
Acessibilidade de formulários
Para formulários de contato e outras situações onde o usuário precisa inserir dados, a acessibilidade é especialmente importante.
Validação inline
Exiba mensagens de erro imediatamente nos eventos blur / input e integre os seguintes atributos aria:
aria-invalid="true"— notifica que a entrada é inválidaaria-describedby— referencia o ID da mensagem de erro
<input
type="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" role="alert">Por favor, insira um endereço de e-mail válido</p>
Marcação de campos obrigatórios
Apenas a marca visual * não é suficiente. Adicione texto complementar para leitores de tela.
<span aria-hidden="true">*</span>
<span class="sr-only">(obrigatório)</span>
Atributo role em elementos figure
Ao definir role="img" em elementos <figure>, os elementos filhos ficam ocultos para leitores de tela. Em componentes que contêm ícones e texto descritivo (InsightGrid, ProcessFigure, Timeline), altere para role="group" para manter o conteúdo interno acessível.
Atributo role em elementos de lista
Quando list-style: none é definido via CSS, há um bug conhecido onde o leitor de tela do Safari (VoiceOver) não reconhece como lista.
Adicione role="list" aos elementos <ol> / <ul> do breadcrumb, sidebar e footer para contornar o problema. Verifique todas as listas com aparência personalizada.
Outras melhorias
Atributos width/height em imagens
Imagens sem width e height explícitos causam CLS (Cumulative Layout Shift) quando o layout muda ao completar o carregamento. Especifique o tamanho para todas as imagens, incluindo avatares (32×32, 48×48, 64×64px) e thumbnails do YouTube (480×360px).
aria-live no slider Hero
Sliders com troca automática não comunicam as mudanças aos usuários de leitores de tela. Prepare uma região aria-live="polite" e notifique com texto como “Slide 1 / 4: 〇〇”.
aria-labelledby em dialog
Elementos <dialog> devem referenciar o ID do elemento de título com aria-labelledby, permitindo que o leitor de tela leia o propósito do modal.
aria-current na paginação
Defina aria-current="page" no número da página atual, notificando ao leitor de tela que é a “página atual”.
Atualização de aria-label no botão copiar
Ao copiar com sucesso para a área de transferência, atualize dinamicamente o aria-label para “Copiado” e notifique a mudança de estado ao leitor de tela.
Conclusão
Melhorias de acessibilidade são individualmente pequenas mudanças, mas quando acumuladas, melhoram significativamente a qualidade geral do site. As três mais eficazes foram:
- Aplicação global de focus-visible: melhoria drástica na navegação por teclado
- Correção da razão de contraste: apenas
text-slate-400→text-slate-500e WCAG AA aprovado - Notificação SR para links externos: aplicação automática em todos os links combinando com
rehype-external-links
Recomendamos começar escaneando seu site com axe DevTools e resolvendo primeiro os problemas detectáveis automaticamente.
Série que inclui este artigo
Este artigo faz parte da série “Guia de melhoria de qualidade do site Astro”. Melhorias de performance, SEO e UX também são apresentadas em artigos individuais.
Como conduzir melhorias de acessibilidade
Inspeção automática
Use axe DevTools e Lighthouse para identificar problemas detectáveis automaticamente.
Inspeção manual
Teste navegando com teclado e leitor de tela.
Correção
Adicione atributos aria, corrija contraste e adicione estilos de foco.
Reinspeção
Confirme pontuação 100 no Accessibility do PageSpeed.
- Concluído: Razão de contraste do texto é 4.5:1 ou superior (3:1 para texto grande)
- Concluído: Todos os elementos interativos têm estilo focus-visible
- Concluído: Ícones decorativos têm aria-hidden="true"
- Concluído: Links externos têm notificação para leitores de tela
- Concluído: Formulários têm validação inline com integração aria-invalid
- Concluído: Imagens têm atributos width/height (prevenção de CLS)
- Concluído: Elementos de lista têm role="list" (solução para list-style:none)
Qual a diferença entre axe DevTools e Lighthouse?
Devo adicionar atributos aria em todos os elementos?
Se o Accessibility do PageSpeed está em 100 pontos, o site é compatível com WCAG?
Gui
CEO da Acecore. Engenheiro versátil que trabalha com desenvolvimento de sistemas, produção web, operações de infraestrutura e educação em TI. Gosta de resolver desafios organizacionais e humanos por meio da tecnologia.
Quer saber mais sobre nossos serviços?
Oferecemos suporte abrangente em desenvolvimento de sistemas, design web, design gráfico e educação em TI.