Compreendendo Papéis de Acessibilidade em HTML
Os papéis de acessibilidade informam às tecnologias assistivas o que um elemento é, não como ele se parece. Quando um leitor de tela encontra um botão, ele precisa saber que é um botão—seja um elemento nativo <button> ou um componente personalizado com role="button". Errar nisso significa que milhões de usuários não conseguem navegar pela sua interface de forma eficaz.
Este guia explica como os papéis de acessibilidade se encaixam na árvore de acessibilidade mais ampla, quando usar papéis ARIA versus HTML semântico, e as melhores práticas que mantêm seu código acessível e de fácil manutenção.
Pontos-Chave
- Os papéis de acessibilidade definem o que um elemento é para as tecnologias assistivas, não sua aparência visual
- A árvore de acessibilidade contém nome, papel e valor/estado para cada elemento
- O HTML semântico fornece papéis implícitos—use ARIA apenas quando o HTML não for suficiente
- Testar com tecnologias assistivas reais garante que sua implementação funcione para usuários reais
Como os Papéis Funcionam na Árvore de Acessibilidade
Toda página web tem duas árvores: a árvore DOM com a qual você está familiarizado, e a árvore de acessibilidade que as tecnologias assistivas realmente leem. A árvore de acessibilidade segue um modelo simples: cada elemento tem um nome, papel e valor/estado.
<!-- Elemento DOM -->
<button aria-pressed="true">Mute</button>
<!-- Representação na árvore de acessibilidade -->
Name: "Mute"
Role: button
Value/State: pressed=true
O navegador constrói automaticamente essa árvore de acessibilidade a partir do seu HTML, mapeando elementos semânticos para seus papéis implícitos. Um elemento <nav> se torna um marco de navegação, um <button> se torna um widget de botão. Os papéis ARIA permitem que você modifique essa árvore quando o HTML nativo não é suficiente—mas eles devem ser seu último recurso, não sua primeira escolha.
As Quatro Principais Categorias de Papéis
Papéis de Marco (Landmark Roles)
Os papéis de marco definem regiões da página para navegação. O HTML5 moderno fornece a maioria deles nativamente:
<header>→ papel banner (quando não estiver dentro de<article>ou<section>)<nav>→ papel navigation<main>→ papel main<aside>→ papel complementary<footer>→ papel contentinfo (quando não estiver dentro de<article>ou<section>)
Melhor prática: Use elementos HTML semânticos em vez de <div role="navigation">. A redundância de <nav role="navigation"> não agrega valor—o elemento já tem esse papel implicitamente.
Papéis de Widget (Widget Roles)
Os papéis de widget descrevem controles interativos. Estes são cruciais para componentes personalizados que não podem usar elementos nativos:
<!-- Bom: Interface de abas personalizada -->
<div role="tablist">
<button role="tab" aria-selected="true">Configurações</button>
<button role="tab" aria-selected="false">Perfil</button>
</div>
<!-- Ruim: ARIA desnecessário -->
<button role="button">Clique aqui</button> <!-- Redundante -->
Papéis de Estrutura de Documento
Esses papéis descrevem a organização do conteúdo: cabeçalhos, listas, artigos e separadores. Novamente, prefira HTML semântico:
<!-- Prefira isto -->
<article>
<h2>Título do Artigo</h2>
</article>
<!-- Em vez disto -->
<div role="article">
<div role="heading" aria-level="2">Título do Artigo</div>
</div>
Papéis Abstratos (Abstract Roles)
Papéis abstratos como command ou composite são modelos fundamentais no WAI-ARIA. Nunca use estes diretamente—eles existem apenas para que a especificação defina outros papéis.
Discover how at OpenReplay.com.
Melhores Práticas Modernas para Papéis ARIA
Prefira HTML Semântico Primeiro
A primeira regra do ARIA é não usar ARIA. Elementos HTML nativos vêm com suporte de teclado integrado, gerenciamento de foco e semântica de acessibilidade:
<!-- Sempre prefira isto -->
<button onclick="submit()">Enviar</button>
<!-- Em vez deste antipadrão -->
<div role="button" tabindex="0" onclick="submit()">Enviar</div>
A versão com <div> requer JavaScript adicional para suporte de teclado, estilo de foco e ativação adequada—trabalho que o botão nativo faz automaticamente.
Evite Papéis de Marco Redundantes
Desde o HTML5, adicionar papéis explícitos a elementos semânticos é desnecessário e pode causar confusão:
<!-- Não faça isto -->
<main role="main">
<nav role="navigation">
<header role="banner">
<!-- Estes elementos já têm papéis implícitos -->
<main>
<nav>
<header>
Nunca Sobrescreva Papéis Interativos Nativos
Mudar o papel de um botão quebra seu comportamento esperado:
<!-- Nunca faça isto -->
<button role="heading">Título da Seção</button>
<!-- Isto quebra a interação por teclado e as expectativas do leitor de tela -->
Quando Papéis Personalizados Fazem Sentido
Componentes personalizados às vezes genuinamente precisam de papéis ARIA. Aqui estão casos de uso válidos:
Padrão de Diálogo Personalizado
<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
<h2 id="dialog-title">Confirmar Ação</h2>
<button>Cancelar</button>
<button>Confirmar</button>
</div>
Interface de Abas Personalizada
<div role="tablist" aria-label="Configurações do usuário">
<button role="tab" aria-selected="true" aria-controls="panel-1">Geral</button>
<button role="tab" aria-selected="false" aria-controls="panel-2">Privacidade</button>
</div>
<div role="tabpanel" id="panel-1">Conteúdo das configurações gerais</div>
Lidando com Descrições e Rótulos
Para nomes e descrições acessíveis, siga esta hierarquia:
- Texto visível (melhor para todos os usuários)
aria-labelledby(referencia texto visível em outro lugar)aria-describedby(adiciona informações suplementares)aria-label(quando texto visível não é possível)
<button aria-describedby="help-text">Excluir</button>
<span id="help-text">Esta ação não pode ser desfeita</span>
Nota: aria-description está emergindo no WAI-ARIA 1.3, mas tem suporte limitado. Use aria-describedby para código em produção.
Antipadrões Comuns a Evitar
Botões baseados em div: Criar <div role="button"> quando <button> funciona perfeitamente
Excesso de papéis: Adicionar papéis a cada elemento “por precaução”
Semântica conflitante: <h2 role="button"> mistura estrutura e interação
Papéis redundantes: <nav role="navigation"> não agrega valor
Testando Sua Implementação
Sempre verifique os papéis com tecnologias assistivas reais. As ferramentas de desenvolvedor dos navegadores agora incluem inspetores de árvore de acessibilidade—use-os para ver exatamente o que os leitores de tela percebem. Teste com NVDA no Windows ou VoiceOver no macOS para garantir que seus papéis se traduzam em uma experiência utilizável.
Conclusão
Os papéis de acessibilidade existem para descrever o que algo é, não como parece. O HTML semântico nativo fornece a maioria dos papéis implicitamente—use-o primeiro. Reserve os papéis ARIA para componentes genuinamente personalizados onde o HTML não é suficiente. Quando você usar ARIA, certifique-se de que esteja alinhado com as diretrizes WCAG e teste com tecnologias assistivas reais. Lembre-se: nenhum ARIA é melhor do que ARIA mal implementado.
Perguntas Frequentes
Não, cada elemento pode ter apenas um atributo role. Se você precisar de múltiplos significados semânticos, considere reestruturar seu HTML para usar elementos aninhados ou escolher o papel único mais apropriado que represente o propósito principal do elemento.
Absolutamente não. A maioria dos elementos HTML tem papéis implícitos que funcionam perfeitamente sem ARIA. Adicione papéis apenas ao criar widgets personalizados ou quando o HTML semântico não puder expressar a funcionalidade necessária. O uso excessivo de ARIA frequentemente cria mais problemas de acessibilidade do que resolve.
ARIA sempre prevalece sobre a semântica HTML nativa, o que pode quebrar o comportamento esperado. Por exemplo, adicionar role heading a um botão remove toda a funcionalidade de botão para leitores de tela. É por isso que você nunca deve sobrescrever papéis de elementos interativos nativos.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.