O "Botão Perfeito" Que Esconde um Bug

O "Botão Perfeito" Que Esconde um Bug

Jul 09, 2026 semantic-html web-development accessibility frontend best-practices

Por Que Seus Botões Estão Quebrando a Acessibilidade do Seu Site

Eu vou te contar um segredo que todo desenvolvedor aprende da pior maneira.

Você está montando um componente, o design pede um botão. Não um botão qualquer — um botão diferenciado. Com um efeito hover especial, talvez aquele gradiente que muda quando a pessoa clica. Aí você pensa: "Vou fazer rapidinho, bota um <div> aqui, coloca um CSS bonito e pronto."

Fica lindo no Figma. Funciona no seu demo. Depois um usuário real tenta navegar pelo site usando só o teclado, ou usa um leitor de tela, e aí... caos.

O problema não é o seu CSS. O problema é que você pediu para um <div> fazer o trabalho que nunca foi dele.

O Div Que Tentou Ser um Botão

Vamos ser honestos sobre o que normalmente acontece. Você precisa de um botão com visual específico. Cria um <div>, coloca class="btn", estiliza até ficar idêntico ao design. Fica perfeito.

Mas agora o botão precisa funcionar como botão.

Aí você adiciona um event listener de click. Depois um estado de hover. Depois uma borda de focus para quem usa teclado. Aí percebe que Enter e Espaço não funcionam e adiciona listeners de keydown. O botão precisa ficar desabilitado às vezes, então adiciona uma classe .disabled que esperamos que bloqueie todas as interações corretas.

Em algum momento, você adiciona role="button" e tabindex="0" para o leitor de tela não ignorar completamente sua criação.

Parabéns. Você construiu um objeto com formato de botão que precisa de umas 200 linhas de JavaScript para tentar imitar o que o navegador te daria de graça.

É assim que funciona "pagar o aluguel" de decisões arquiteturais ruins. Cada linha de gambiarra é juros sobre a escolha original de usar o elemento errado.

O Contrato Invisível

A verdade é que elementos HTML nativos vêm com um contrato de interação completo que a maioria dos devs só percebe quando ele está faltando.

Quando você usa um <button> de verdade, você recebe:

  • Tratamento automático de teclado — Enter e Espaço funcionam exatamente como o usuário espera
  • Gestão de foco correta — Entra na ordem de tabulação naturalmente, pode receber foco programaticamente
  • Comportamento de estado desabilitado — Bloqueia toda interação, deixa de ser focável, é anunciado como desabilitado
  • Participação em formulários — Envia formulários, respeita validação, participa do form.reset()
  • Semântica de acessibilidade — Leitores de tela announceiam como botão sem precisar de ARIA adicional
  • Convenções da plataforma — Usuários já sabem como botões se comportam porque botões se comportam igual em todo lugar

Com um <div> vestido de botão, você recebe... o CSS. Todo o resto fica por sua conta. E aqui está o segredo: por mais cuidadoso que você seja, sua implementação vai ser pior do que o que o navegador fornece. Navegadores têm equipes de engenheiros otimizando esses comportamentos em diferentes plataformas, casos extremos e tecnologias assistivas. Seu botão customizado só tem você.

A Pergunta Certa Não É "Consigo Estilizar?"

É aqui que a colaboração entre design e engenharia brilha ou cria problemas técnicos. Muitos devs interpretam "HTML semântico" como "aceitar os estilos feios que o navegador impõe". Não é nada disso.

A pergunta não é "consigo fazer ter uma aparência diferente?" — porque sim, consegue. A pergunta é: "quais comportamentos nativos devem sobreviver à estilização?"

Um <button> pode ter qualquer tratamento visual que você quiser. Você pode remover todo estilo padrão com appearance: none. Pode adicionar gradientes, sombras, animações, fontes customizadas — o que o design exigir. O contrato de interação do navegador não liga para a aparência do seu botão.

O que você não consegue fazer facilmente com um <div> é replicar o que o navegador te dá automaticamente. Então escolha suas batalhas: gaste energia de engenharia no que torna seu produto único, não em reinventar botões.

Construindo Para a Web Real

Seus usuários não usam seu produto em um ambiente controlado. Eles navegam entre campos com as mãos no teclado. Usam comandos de voz. Aumentam o zoom para 300% porque é assim que funciona melhor para eles. Usam navegadores diferentes, sistemas operacionais diferentes, tecnologias assistivas diferentes.

A plataforma web te dá uma vantagem enorme com HTML semântico. Elementos nativos são acessíveis por padrão, navegáveis por teclado por padrão, funcionais em qualquer plataforma por padrão. Quando você lucha contra essa infraestrutura, não está apenas criando mais trabalho para si mesmo — está criando componentes que vão falhar de formas sutis para usuários reais.

Da próxima vez que você estiver prestes a pegar um <div> com role="button", pergunte-se: estou construindo algo que genuinamente precisa de uma implementação customizada, ou estou só com medo da tag <button>?

Porque a solução boring costuma ser a correta. E "o navegador cuida disso corretamente" é uma feature, não uma limitação.

A web semântica não é sobre seguir regras. É sobre usar as ferramentas que foram feitas para o trabalho — e gastar sua energia onde realmente faz diferença.

Read in other languages:

EL CS UZ TR SV FI RO PL NB NL HU IT FR ES DE DA ZH-HANS EN