Ir para o conteúdo principal
Niquelao Acessibilidade web e desenvolvimento front-end em espanhol: padrões WCAG, widgets acessíveis e extensões para Firefox, explicados com código real.

Alguns links neste site são links de afiliados: se você comprar através deles, podemos ganhar uma comissão sem custo adicional para você. Isso nunca afeta nossas recomendações. Consulte nossa divulgação de afiliados para mais detalhes. Divulgação de afiliados.

ARIA Role Button: Guia Completo e Prático

O aria role button é um rol ARIA que faz com que as tecnologias de assistência anunciem um contêiner genérico como botão, mas não aporta o comportamento: é necessário adicionar tabindex="0", gerenciar Enter e Espaço e refletir o estado com aria-pressed ou aria-disabled. A especificação WAI-ARIA 1.2 define esta função dentro da categoria de widget, e a primeira regra da ARIA recomenda usar um <button> nativo sempre que possível.

O aria role button pertence à taxonomia de papéis do WAI-ARIA, o padrão do W3C que descreve a semântica acessível para interfaces web. Quando um elemento recebe role="button", a árvore de acessibilidade que constrói os leitores de tela (NVDA, JAWS, VoiceOver, Narrator) deixa de expô-lo como um div ou um span genérico e apresentá-lo como um controle acionável. A diferença é enorme para quem navega com o leitor de tela: sem o papel, o usuário ouve “grupo” ou simplesmente texto; com o papel, ouve “botão” e sabe que pode ativá-lo.

A confusão habitual é acreditar que role="button" converte um div em um botão funcional. Não converte. O papel apenas muda a semântica anunciada; o comportamento —receber foco, responder ao teclado, disparar a ação— continua sendo responsabilidade do desenvolvedor. Esta separação entre semântica e comportamento é a causa da maioria dos erros que ocorrem neste papel.

WAI-ARIA foi publicada como recomendação do W3C e sua versão 1.2 é a referência vigente para funções, estados e propriedades. A função button é uma das funções de widget mais antigas e estabelecidas de acordo com a especificação, presente desde ARIA 1.0.

Quando usar role=“button” e quando não

A primeira regra de ARIA, reconhecida nas práticas de autoria de WAI-ARIA (Práticas de Autoria WAI-ARIA), é importante: se existir um elemento HTML nativo com a semântica e o comportamento que você precisa, use-o. <button> ya trae o rol implícito, o foco do teclado, a ativação com Enter e Espaço, e o estado desabilitado. Reimplementar tudo isso com a ária role role="button" é trabalho extra e fonte de bugs.

Existem, sem embargo, cenários legítimos para o papel. O mais comum é quando o marcador está condicionado pela estrutura ou pelo CMS e não é possível introduzir um <button> sem quebrar o layout ou o JavaScript existente. Outro caso são os componentes que devem se comportar como botão, mas cuja estrutura interna exige um contêiner específico, como certos widgets de terceiros.

Relacionado: — com plano gratuito para começar hoje mesmo.

Um terceiro cenário, mais discutível, é o elemento que você tem um papel nativo distinto e precisa ser apresentado como um botão. Aqui estou convencido de que o projeto não está forçando um equívoco semântico. Se algo parece um botão, mas na realidade navegue para outra página, o correto é um link <a>, não um botão.

SituaçãoSolução recomendadaMotivo
Ação em formulário ou interface<botão> nativoRol, foco e teclado incluídos
Navegação para outro URL<a href>Semântica de link correto
Contenedor não modificávelrole="botão" + teclado + estadosÚnico caso onde o papel aporta
Botão de alternância (ligar/desligar)<button aria-pressed>Estado exposto nativamente
Botão desativado<button disabled>Estado e foco gerenciados

Como implementar um botão com role=“button” corretamente

Um botão baseado em role="button" precisa cobrir quatro frentes: foco, teclado, estado e nome acessível. Omitir qualquer um deles produz um controle que “parece” acessível, mas falha em testes reais.

O foco é habilitado com tabindex="0", que insere o elemento na ordem de tabulação natural. Nunca usa tabindex com valores positivos: altera a ordem de tabulação de toda a página e gera saltos impredecíveis. O valor 0 é o correto para elementos interativos personalizados.

Vale a pena dar uma olhada: — Acessibilidade gerenciada: automatização combinada com revisão humana.

O teclado requer o gerenciamento das teclas: Enter e Espaço. Um <button> nativo responde a ambos, mas um div com uma função de botão ária não o faz por si só. Você deve ouvir keydown e executar a ação quando a tecla é Enter ou Space, evitando também o deslocamento de página que provoca Espaço por defeito. Este detalhe é passado por alto com frequência e deixa os botões que só funcionam com mouse.

O estado é comunicado com atributos ARIA. Um botão de alternância usa aria-pressed="true" ou "false" para indicar se está ativo. Um botão desativado usa aria-disabled="true", que indica o estado, mas não impede a interação por si só: há que bloquear a ação no código. A diferença entre aria-disabled e o atributo nativo disabled é importante, porque o primeiro mantém o elemento enfocable e o segundo o remove da ordem de tabulação.

O nome acessível é construído com o texto visível do elemento o, se não houver texto, com aria-label ou aria-labelledby. Um botão sem nome acessível é um botão que o leitor de tela anuncia como “botão” puramente, sem pista do que faz.

<div
  role="botão"
  tabindex="0"
  aria-pressed="false"
  id="btn-modo"
>
  Modo escuro
</div>

<script>
  const btn = document.getElementById('btn-modo');
  function toggle() {
    const ativo = btn.getAttribute('aria-pressed') === 'true';
    btn.setAttribute('aria-pressionado', String(!activo));
  }
  btn.addEventListener('click', alternar);
  btn.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      alternar();
    }
  });
</script>

O exemplo anterior cobre foco, teclado, estado e nome. É o mínimo viável para que o controle possa ser usado com o leitor de tela e o teclado.

Erros frequentes e como detectá-los

O erro mais estendido é aplicar role="button" sem tabindex, que produz um botão inalcançável no teclado. As ferramentas automáticas são detectadas como “elemento com função interativa não focalizável”, uma das violações mais relatadas em auditorias de acessibilidade.

O segundo erro não permite gerenciar o teclado. Um div com uma função de botão ária e tabindex, mas sem manejadores de tecla recebem foco e não respondem a Enter nem Espaço. O usuário do teclado fica preso: você pode focar o botão, mas não ativá-lo.

Relacionado: — A que acredita sua experiência e acessibilidade.

O terceiro erro é usar role="button" em um link. Isso rompe a semântica de navegação e confunde os leitores de tela, que anunciam um “botão” quando o usuário espera um link. Se o elemento navegar, deverá ser um link.

O quarto erro é esquecer o estado nos botões de alternância. Um botão que muda entre os modos sem aria-pressionado deixa o usuário sem saber em que estado ele se encontra. O atributo é a única forma de comunicação e esse estado de forma programática.

Para detectar esses problemas, as ferramentas automáticas como axe, Lighthouse ou WAVE sinalizam violações de rol e foco, mas não validam o comportamento do teclado nem a lógica de estado. Essa parte exige teste manual: navegue com Tab, ative com Enter e Espacio e ouça a saída do leitor de tela. A combinação de auditoria automática e teste manual é a única forma confiável de validar um botão personalizado.

Se você estiver comprando: — Superposição de IA que promete cumprimento WCAG em 48 horas.

Como testar um botão com role=“button”

O teste começa pelo teclado. Corrija a página com Tab e verifique se o botão com o botão Aria Role recebe o foco visível. Pulsa Enter e Espaço por separado: ambos devem disparar a ação. Se o Espacio mudar a página em vez de ativar o botão, falta o preventDefault.

A segunda tentativa é com o leitor de tela. NVDA no Windows, VoiceOver no macOS e Narrator no Windows são as referências mais usadas. Ao focar o botão, o leitor deve anunciar o rol (“botão”), o nome acessível e o estado se o tiver. Se anuncia “grupo” ou não menciona o estado, algo falha.

A terceira tentativa é a ordem de foco. O botão deve aparecer na ordem lógica de tabulação, nem antes nem depois de onde corresponde visualmente. Os tabindex positivos rompem esta ordem e são um indicador claro de má implementação.

A quarta prova é de contraste e foco visível. O indicador de foco não deve ser removido com outline: none sem substituí-lo por uma alternativa visível. Um botão que recebeu foco, mas não mostra o usuário do teclado sem referência de onde está.

Alternativas modernas ao botão rol

O elemento <button> nativo continua sendo a melhor opção em 2024 e em qualquer projeto novo. Aporta rol, foco, teclado e estados sem código adicional, e os navegadores o tratam de forma consistente.

Os elementos personalizados ou Web Components são oferecidos de outra maneira. Um componente que estende HTMLElement pode encapsular o comportamento do botão e expô-lo com a semântica correta, mas requer gerenciamento manual do foco e do teclado igual ao role="button". A venda é a reutilização; a desventaja, a mesma responsabilidade de implementação.

Las ARIA in HTML (regras que definem quais papéis ARIA são permitidos sobre cada elemento HTML) desaconsejan sobrescrever papéis nativos. Aplicar a ária role role="button" em um <button> é redundante; aplique-o a um <a> com href é contraproducente. A recomendação geral é reservar o papel para contêineres sem semântica própria.

Principais conclusões

  • role="button" muda apenas a semântica anunciada; o foco, o teclado e o estado são implementados manualmente.
  • A primeira regra da ARIA recomenda usar <button> nativo sempre que o marcado permitir.
  • Um botão com ária role button necessário tabindex="0", gerenciamento de Enter e Espaço, nome acessível e estado com aria-pressionado ou aria-disabled.
  • As ferramentas automáticas detectam falta de foco, mas o comportamento do teclado e o estado exigem que você verifique o manual com o leitor de tela.
  • Nunca use tabindex positivo nem aplique role="button" em links que navegam.

Perguntas frequentes

Qual é a diferença entre role=“button” e o elemento button?

O elemento <button> nativo inclui a função implícita, o foco do teclado, a ativação com Enter e Espaço e o estado desativado sem código adicional. O atributo role="button" apenas traz a semântica anunciada; o resto do comportamento deve ser programado. Por isso, a primeira regra da ARIA recomenda o elemento nativo sempre que for possível.

Você precisa de tabindex com role=“button”?

Si. Um div ou span com role="button" não é enfocado por defeito, assim como tabindex="0" fica fora da ordem de tabulação e é inalcançável com o teclado. O valor correto é 0; Os valores positivos alteram a ordem de tabulação de toda a página e devem ser evitados.

Como foi que uma div com role=“button” responde a Enter e Espaço?

Você deve ouvir o evento keydown e executar a ação quando a tecla for Enter ou Space. No caso do Espacio, convém chamar preventDefault para evitar o deslocamento da página. Sem esses manipuladores, o botão recebe foco, mas não é ativado com o teclado.

Como é que um botão está ativo ou desativado?

Para um botão de alternância, use aria-pressed="true" ou "false" dependendo do estado. Para um botão desativado, use aria-disabled="true", que indica o estado, mas não bloqueia a interação por si só: isso impede a ação no código. O atributo nativo disabled é preferível quando um <button> é usado.

Sim, quando o link navega para outro URL. Sobrescreva o papel de um <a href> com role="button" rompe a semântica de navegação e confunda os leitores de tela, que anunciam “botão” quando o usuário espera um link. Se o elemento navegar, você deve manter a rolagem do link.

O que as ferramentas detectaram erros com role=“button”?

Ferramentas automáticas como axe, Lighthouse ou WAVE sinalizam violações como falta de foco em elementos com função interativa. No entanto, o comportamento do teclado não é válido nem a lógica de estado, portanto a verificação confiável combina a audição automática com a verificação manual usando NVDA, VoiceOver ou Narrator.

Perguntas frequentes

Qual é a diferença entre role='button' e o elemento button?

O elemento <button> nativo inclui a função implícita, o foco do teclado, a ativação com Enter e Espaço e o estado desativado sem código adicional. O atributo role='button' apenas indica a semântica anunciada; o resto do comportamento deve ser programado. Por isso, a primeira regra da ARIA recomenda o elemento nativo sempre que for possível.

Você precisa de tabindex com role='button'?

Si. Uma div ou span com role='button' não é enfocada por defeito, assim como sin tabindex='0' fica fora da ordem de tabulação e é inalcançável com o teclado. O valor correto é 0; Os valores positivos alteram a ordem de tabulação de toda a página e devem ser evitados.

Como foi que uma div com role='button' respondeu a Enter e Espaço?

Você deve ouvir o evento keydown e executar a ação quando a tecla é Enter ou Espaço. No caso do Espacio, convém chamar preventDefault para evitar o deslocamento da página. Sem esses manipuladores, o botão recebe foco, mas não é ativado com o teclado.

Como é que um botão está ativo ou desativado?

Para um botão de alternância, use aria-pressed='true' ou 'false' dependendo do estado. Para um botão desativado, use aria-disabled='true', que indica o estado, mas não bloqueia a interação por si só: isso impede a ação no código. O atributo nativo desativado é preferível quando um <button> é usado.

É difícil usar role='button' em um link?

Sim, quando o link navega para outro URL. Sobrescreva o papel de um <a href> com role='button' rompe a semântica de navegação e confunda os leitores de tela, que anunciam 'botão' quando o usuário espera um link. Se o elemento navegar, você deve manter a rolagem do link.

O que as ferramentas detectaram erros com role='button'?

Ferramentas automáticas como axe, Lighthouse ou WAVE sinalizam violações como falta de foco em elementos com função interativa. No entanto, o comportamento do teclado não é válido nem a lógica de estado, portanto a verificação confiável combina a audição automática com a verificação manual usando NVDA, VoiceOver ou Narrator.


Cumprir WCAG sem tocar no código?

Superposição de IA que promete cumprimento WCAG em 48 horas