Acessibilidade em React: Além do aria-label
Colocar
aria-labelTrabalhei com dashboards LGPD, e-commerce e portais enterprise. Estas práticas são as que mais impactam quem usa leitor de tela ou só o teclado.
1. HTML semântico antes de ARIA
A regra do WAI-ARIA continua válida: se existe elemento nativo, use ele.
// ❌ div disfarçado de botão <div role="button" tabIndex={0} onClick={handleClick}>Salvar</div> // ✅ botão real <button type="button" onClick={handleClick}>Salvar</button>
Use
<nav><main><article><button>h1h2div2. Foco visível e ordem de tabulação
Todo elemento interativo precisa de
:focus-visiblebutton:focus-visible { outline: 3px solid rgba(124, 58, 237, 0.55); outline-offset: 4px; }
Em modais e menus, prenda o foco dentro do painel e devolva o foco ao botão que abriu ao fechar. Teste só com Tab e Shift+Tab.
3. Acordeões e painéis expansíveis
Para FAQ, filtros e menus, o padrão correto é:
- no botão que abre
aria-expanded - apontando para o id do painel
aria-controls - no conteúdo com
role="region"aria-labelledby
<button aria-expanded={isOpen} aria-controls="faq-panel-1" id="faq-trigger-1" > Pergunta </button> <div id="faq-panel-1" role="region" aria-labelledby="faq-trigger-1"> Resposta </div>
Evite
display: none4. Live regions para mudanças dinâmicas
Busca, filtros e toasts devem anunciar o que mudou:
<div aria-live="polite" aria-atomic="true" className="visually-hidden"> {resultCount === 0 ? 'Nenhum resultado encontrado' : `${resultCount} resultados`} </div>
Use
politeassertive5. Teste com ferramentas e com teclado
Automatize o básico com axe-core ou eslint-plugin-jsx-a11y, mas valide manualmente:
- Navegação só com teclado
- VoiceOver (macOS) ou NVDA (Windows)
- Contraste com Lighthouse ou DevTools
Um
aria-labelConclusão
Acessibilidade em React é trabalho de produto: HTML certo, foco previsível, estados anunciados e testes contínuos.
Comece pelo HTML nativo, trate o teclado com prioridade e, quando possível, teste com pessoas reais. Interfaces acessíveis costumam ser mais robustas para todo mundo.
