Acessibilidade na prática: checklist para devs que não são especialistas
1. Fundamentos essenciais: por que acessibilidade importa (e não é só sobre leis)
Acessibilidade digital não é um bônus — é um direito. No Brasil, cerca de 18,6 milhões de pessoas com 2 anos ou mais (8,9% da população) têm alguma deficiência, segundo o IBGE. Ignorar acessibilidade significa excluir milhões de usuários do seu produto.
O impacto real vai além de cumprir leis como a Lei Brasileira de Inclusão (LBI, nº 13.146/2015). Usuários com deficiência visual dependem de leitores de tela (NVDA, JAWS, VoiceOver). Pessoas com limitações motoras navegam exclusivamente por teclado. Quem tem baixa visão precisa de contraste adequado.
Mitos comuns atrapalham a adoção: "acessibilidade é só para cegos" (ignora deficiências auditivas, motoras e cognitivas) e "vai deixar o design feio" (na verdade, designs acessíveis são mais usáveis para todos).
A tríade de conformidade é a WCAG 2.2 (Web Content Accessibility Guidelines), organizada em três níveis: A (mínimo), AA (recomendado) e AAA (avançado). Para a maioria dos projetos, o nível AA é o alvo prático.
2. Semântica HTML: a base invisível que leitores de tela entendem
Leitores de tela interpretam a estrutura do HTML para navegar pelo conteúdo. Sem semântica correta, a experiência se torna um caos.
Landmarks são regiões que ajudam na navegação rápida:
<header role="banner">
<nav role="navigation" aria-label="Navegação principal">
<ul>
<li><a href="/">Início</a></li>
<li><a href="/produtos">Produtos</a></li>
</ul>
</nav>
</header>
<main role="main">
<article>
<h1>Título principal</h1>
<p>Conteúdo do artigo...</p>
</article>
</main>
<aside role="complementary">
<h2>Artigos relacionados</h2>
</aside>
<footer role="contentinfo">
<p>© 2025</p>
</footer>
Headings devem seguir ordem hierárquica sem pular níveis:
<h1>Título da página</h1>
<h2>Seção principal</h2>
<h3>Subseção</h3>
<h2>Outra seção</h2>
ARIA (Accessible Rich Internet Applications) deve complementar, não substituir, a semântica nativa. Regra de ouro: use HTML semântico primeiro; ARIA apenas quando não houver elemento nativo.
Formulário acessível com fieldset e legend:
<form>
<fieldset>
<legend>Dados pessoais</legend>
<label for="nome">Nome completo:</label>
<input type="text" id="nome" name="nome" required>
<label for="email">E-mail:</label>
<input type="email" id="email" name="email" required>
</fieldset>
<fieldset>
<legend>Preferências de contato</legend>
<input type="radio" id="contato-email" name="contato" value="email">
<label for="contato-email">E-mail</label>
<input type="radio" id="contato-telefone" name="contato" value="telefone">
<label for="contato-telefone">Telefone</label>
</fieldset>
<button type="submit">Enviar</button>
</form>
3. Navegação por teclado: o teste que qualquer dev pode fazer
Testar com teclado é o exame mais simples e revelador. Pressione Tab, Shift+Tab, Enter e Esc. Se algo ficar inacessível, seu código precisa de ajustes.
Foco visível é obrigatório. Nunca remova o outline sem fornecer substituto:
/* Ruim */
button:focus {
outline: none;
}
/* Bom */
button:focus-visible {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
Ordem de tabulação deve seguir a ordem visual. Use tabindex="0" para tornar elementos não interativos focáveis por teclado, e tabindex="-1" para foco programático via JavaScript:
<div tabindex="-1" id="mensagem-erro" role="alert">
Erro: campo obrigatório não preenchido.
</div>
Gerenciamento de foco em modais — essencial para SPAs:
function abrirModal(modalId) {
const modal = document.getElementById(modalId);
modal.style.display = 'block';
modal.setAttribute('aria-hidden', 'false');
// Foco no primeiro elemento interativo
const primeiroElemento = modal.querySelector('button, [href], input, select, textarea');
if (primeiroElemento) primeiroElemento.focus();
// Travar foco dentro do modal
modal.addEventListener('keydown', function(e) {
if (e.key === 'Escape') fecharModal(modalId);
});
}
4. Contraste e cores: enxergando além do design bonito
A WCAG 2.2 exige relação de contraste mínima de 4.5:1 para texto normal e 3:1 para texto grande (acima de 18px ou 14px negrito) e componentes interativos.
Ferramentas práticas que todo dev deve conhecer:
- DevTools do navegador: inspecione um elemento e veja a relação de contraste na aba "Styles"
- axe DevTools: extensão que escaneia a página e aponta violações
- WAVE: ferramenta visual que sobrepõe indicadores de acessibilidade na página
Nunca dependa apenas de cor para transmitir informação. Estados de erro, sucesso e links precisam de indicadores adicionais:
/* Ruim: apenas cor vermelha indica erro */
.input-erro {
border-color: red;
}
/* Bom: cor + ícone + texto */
.input-erro {
border-color: #d32f2f;
background-image: url('icone-erro.svg');
background-repeat: no-repeat;
background-position: right 10px center;
}
.input-erro + .mensagem-erro {
color: #d32f2f;
font-size: 0.875em;
}
5. Imagens, mídia e animações: conteúdo que não pode ser ignorado
Texto alternativo (alt) segue regras simples:
- Imagens informativas: descreva o conteúdo
- Imagens decorativas:
alt=""(vazio) - Imagens com texto: repita o texto no alt
- Botões com ícone: use
aria-label
<!-- Informativa -->
<img src="grafico-vendas-2024.png" alt="Gráfico de barras mostrando vendas de R$ 50 mil em janeiro a R$ 80 mil em dezembro de 2024">
<!-- Decorativa -->
<img src="linha-divisoria.svg" alt="" role="presentation">
<!-- Botão com ícone -->
<button aria-label="Fechar modal">
<img src="icone-fechar.svg" alt="">
</button>
Vídeos e áudio precisam de legendas e transcrições. Evite autoplay — usuários com deficiência cognitiva podem se sentir sobrecarregados.
Movimento e epilepsia: respeite prefers-reduced-motion e evite flashes acima de 3 Hz:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
6. Formulários e feedback: erros que todo mundo entende
Mensagens de erro devem ser claras e associadas ao campo via aria-describedby ou aria-errormessage:
<label for="email-usuario">E-mail:</label>
<input
type="email"
id="email-usuario"
name="email"
required
aria-describedby="email-ajuda"
aria-invalid="true"
aria-errormessage="email-erro"
>
<span id="email-ajuda" class="sr-only">Formato esperado: usuario@exemplo.com</span>
<span id="email-erro" role="alert" class="erro">
<img src="icone-erro.svg" alt="" aria-hidden="true">
E-mail inválido. Use o formato usuario@exemplo.com
</span>
Validação em tempo real não deve bloquear o usuário. Mostre erros após o campo perder o foco (blur), não durante a digitação.
7. Testes rápidos que você pode fazer hoje (checklist final)
Teste manual (5 minutos):
- Desconecte o mouse e navegue apenas com Tab, Shift+Tab, Enter e Esc
- Ative o leitor de tela: NVDA (Windows, gratuito) ou VoiceOver (Mac, nativo)
- Verifique se consegue preencher e enviar um formulário
Ferramentas automatizadas:
- axe DevTools (extensão Chrome/Firefox)
- Lighthouse (aba Accessibility no DevTools)
- WAVE (wave.webaim.org)
Checklist de 5 itens essenciais:
- Headings hierárquicos: há apenas um
<h1>? Os níveis seguem ordem sem pular? - Foco visível: todos os elementos interativos têm indicador de foco claro?
- Contraste mínimo: texto normal ≥ 4.5:1, texto grande ≥ 3:1?
- Labels nos inputs: todo
<input>,<select>e<textarea>tem<label>associado? - Alt nas imagens: imagens informativas têm descrição; decorativas têm
alt=""?
Implementar acessibilidade não exige ser especialista. Exige atenção, testes consistentes e vontade de incluir. Comece pelo checklist acima e, a cada sprint, adicione um novo item. Seu código — e seus usuários — agradecem.
Referências
- WCAG 2.2 — Web Content Accessibility Guidelines (W3C) — Documentação oficial completa com todos os critérios de sucesso, níveis de conformidade e técnicas de implementação.
- axe DevTools — Extensão de acessibilidade (Deque Systems) — Ferramenta automatizada que escaneia páginas e aponta violações de acessibilidade com explicações detalhadas.
- WAVE Web Accessibility Evaluation Tool (WebAIM) — Ferramenta visual que sobrepõe indicadores de acessibilidade diretamente na página, ideal para auditorias rápidas.
- Lei Brasileira de Inclusão (LBI) — Lei nº 13.146/2015 — Marco legal que estabelece direitos das pessoas com deficiência no Brasil, incluindo acessibilidade digital.
- NVDA — NonVisual Desktop Access (NV Access) — Leitor de tela gratuito e de código aberto para Windows, essencial para testar acessibilidade com usuários reais.
- prefers-reduced-motion — CSS Media Query (MDN Web Docs) — Documentação técnica sobre como respeitar preferências de movimento reduzido em animações CSS.
- ARIA Authoring Practices Guide (W3C) — Guia prático de padrões de design acessíveis com exemplos de código para menus, modais, tabs e outros componentes interativos.