Acessibilidade Web (a11y): Um Guia Prático para Desenvolvedores
Aprenda os princípios essenciais de acessibilidade, atributos ARIA, padrões de navegação por teclado e ferramentas de teste que tornam suas aplicações web utilizáveis por todos.
Mais de 1,3 bilhão de pessoas — 16% da população mundial — vivem com alguma forma de deficiência. A acessibilidade web garante que seu site funcione para usuários que dependem de leitores de tela, navegação por teclado, acesso por switch ou outras tecnologias assistivas. Além da inclusão, sites acessíveis têm melhor posicionamento nos mecanismos de busca, melhor desempenho em dispositivos móveis e, muitas vezes, são exigidos por lei.
Os quatro princípios POUR
As Diretrizes de Acessibilidade para Conteúdo Web (WCAG) são baseadas em quatro princípios fundamentais. O conteúdo deve ser:
- Perceptível — As informações devem ser apresentadas de formas que os usuários possam perceber (não apenas visualmente).
- Operável — Todas as funcionalidades devem estar disponíveis via teclado.
- Compreensível — O conteúdo e as interfaces devem ser compreensíveis.
- Robusto — O conteúdo deve ser interpretável por tecnologias assistivas.
O WCAG 2.2 define três níveis de conformidade:
- A — Mínimo (obrigatório)
- AA — Meta padrão para a maioria das organizações
- AAA — Máximo (aspiracional para alguns conteúdos)
A maioria das exigências legais (ADA, EN 301 549, EAA) requer conformidade AA.
HTML semântico em primeiro lugar
A coisa mais impactante que você pode fazer pela acessibilidade é usar o elemento HTML correto para cada situação. Navegadores e leitores de tela já sabem o que fazer com elementos semânticos:
<!-- ❌ Sopa de divs — sem semântica -->
<div class="header">
<div class="nav">
<div class="nav-item" onclick="navigate()">Home</div>
</div>
</div>
<!-- ✅ HTML semântico — leitores de tela entendem isso -->
<header>
<nav>
<a href="/">Home</a>
</nav>
</header>
Principais elementos semânticos e seus papéis:
| Elemento | Papel |
|---|---|
<header>, <footer> |
Regiões de referência (landmarks) |
<nav> |
Referência de navegação |
<main> |
Conteúdo principal (um por página) |
<aside> |
Conteúdo complementar |
<h1>–<h6> |
Hierarquia de títulos |
<button> |
Controle interativo |
<a href> |
Link de navegação |
<label> |
Rótulo de campo de formulário |
<table> |
Dados tabulares |
Imagens e texto alternativo
Toda imagem com significado precisa de um atributo alt descrevendo seu conteúdo. Imagens decorativas recebem alt="" vazio para que os leitores de tela as ignorem:
<!-- Imagem com significado -->
<img src="chart.png" alt="Gráfico de barras mostrando aumento de 40% na receita no 1º trimestre de 2026">
<!-- Imagem decorativa -->
<img src="divider.svg" alt="">
<!-- Botão com ícone — descreva a ação, não o ícone -->
<button>
<img src="trash.svg" alt="Excluir item">
</button>
<!-- Evite: "imagem de" redundante -->
<!-- ❌ --> <img src="cat.jpg" alt="Imagem de um gato">
<!-- ✅ --> <img src="cat.jpg" alt="Gato laranja tigrado sentado no peitoril de uma janela">
Contraste de cores
Usuários com baixa visão ou daltonismo dependem de contraste suficiente entre o texto e o fundo.
Requisitos WCAG AA:
- Texto normal (< 18pt): razão de contraste mínima de 4,5:1
- Texto grande (≥ 18pt ou 14pt em negrito): razão de contraste mínima de 3:1
- Componentes de interface e objetos gráficos: mínimo de 3:1
Não utilize apenas cor para transmitir informações:
<!-- ❌ Indicador de status apenas por cor -->
<span class="text-red-500">Erro</span>
<!-- ✅ Cor + ícone + texto -->
<span class="text-red-500 flex items-center gap-1">
<svg aria-hidden="true"><!-- ícone de erro --></svg>
Erro: Endereço de e-mail inválido
</span>
Formulários: rótulos, erros e descrições
Todo controle de formulário precisa de um rótulo visível e associado:
<!-- ✅ Associação explícita de rótulo -->
<label for="email">Endereço de e-mail</label>
<input id="email" type="email" aria-describedby="email-hint email-error">
<p id="email-hint" class="text-sm text-gray-500">Nunca compartilharemos seu e-mail.</p>
<p id="email-error" role="alert" class="text-sm text-red-600" hidden>
Por favor, insira um endereço de e-mail válido.
</p>
Principais padrões de acessibilidade em formulários:
- Use
for/idpara associar rótulos aos campos - Use
aria-describedbypara textos de dica e mensagens de erro - Use
role="alert"ouaria-live="polite"para mensagens de erro dinâmicas - Use
aria-required="true"ou o atributo nativorequired - Agrupe campos relacionados com
<fieldset>e<legend>
Navegação por teclado
Todos os elementos interativos devem ser acessíveis e operáveis via teclado:
- Tab — avançar pelos elementos focalizáveis
- Shift+Tab — voltar
- Enter/Espaço — ativar botões e checkboxes
- Teclas de seta — navegar dentro de componentes (menus, abas, sliders)
- Escape — fechar modais, dispensar dropdowns
Os indicadores de foco devem ser visíveis. Nunca faça isso sem uma alternativa:
/* ❌ Oculta completamente o indicador de foco */
*:focus { outline: none; }
/* ✅ Estilo de foco personalizado que ainda é visível */
*:focus-visible {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
ARIA: quando e como usar
Os atributos ARIA (Accessible Rich Internet Applications) adicionam significado semântico quando o HTML por si só não é suficiente. A primeira regra do ARIA: não use ARIA se o HTML nativo consegue fazer o trabalho.
<!-- Rotular elementos sem rótulos visíveis -->
<button aria-label="Fechar diálogo">✕</button>
<!-- Descrever o estado expandido -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>
<!-- Região dinâmica para conteúdo em tempo real -->
<div aria-live="polite" aria-atomic="true">
<!-- Leitores de tela anunciam alterações nessa área -->
3 resultados encontrados
</div>
<!-- Papel de referência quando o elemento semântico não está disponível -->
<div role="search">
<input type="search" placeholder="Buscar...">
</div>
Gerenciamento de foco em SPAs e modais
Em aplicações de página única (SPAs), a navegação entre páginas não aciona uma redefinição de foco pelo navegador. Quando uma "página" é carregada, mova o foco para um local significativo:
// Após a navegação, foca no título principal
document.querySelector("h1")?.focus();
Para modais:
- Quando o modal abrir, mova o foco para o primeiro elemento focalizável dentro dele
- Mantenha o foco preso dentro do modal enquanto ele estiver aberto (evite que o Tab alcance o conteúdo ao fundo)
- Quando o modal fechar, retorne o foco ao elemento que o acionou
Testando a acessibilidade
Ferramentas automatizadas (identificam ~30-40% dos problemas)
- Extensão de navegador axe DevTools
- Auditoria de acessibilidade do Lighthouse no Chrome DevTools
- Extensão de navegador WAVE
Testes manuais (necessários para cobertura completa)
- Navegação apenas por teclado — desconecte o mouse e navegue por todo o seu site
- Teste com leitores de tela — NVDA + Firefox (Windows), VoiceOver + Safari (Mac/iOS)
- Zoom a 200% — verifique se nenhum conteúdo é perdido ou se sobrepõe
- Simulação de daltonismo — DevTools do navegador → Rendering → Emulate vision deficiencies
Legibilidade
Uma linguagem simples melhora a acessibilidade para usuários com deficiências cognitivas. Use nossa ferramenta Readability Score para verificar o nível de leitura do seu conteúdo — para o público geral, busque entre a 8ª e a 10ª série.
Melhorias rápidas que você pode fazer hoje
- Adicione texto
alta todas as imagens - Certifique-se de que todos os campos de formulário tenham elementos
<label>associados - Verifique se o contraste de cores atinge 4,5:1 para o texto do corpo
- Adicione estilos
:focus-visiblee nunca remova os contornos sem uma substituição - Use
<button>para ações e<a href>para navegação (nunca o contrário) - Adicione
lang="pt-BR"(ou o idioma apropriado) ao seu elemento<html> - Use um
<h1>por página e mantenha uma hierarquia de títulos lógica
Acessibilidade não é um recurso adicional — é uma característica de qualidade. Criar produtos acessíveis desde o início é muito mais barato do que fazer adaptações depois, e torna seus produtos melhores para todos.