Quando o código diz: "Eu te escuto"
\n\nImagine que você perdeu a visão por um dia. Seu aplicativo de mensagens favorito em Go de repente fica mudo. Os botões não são anunciados, os formulários não podem ser preenchidos e os erros de validação são apenas retângulos vermelhos. Desagradável, não é? Mas para milhões de pessoas com deficiência, isso não é um experimento, é a realidade.
\n\nAcessibilidade (ou a11y — de "a" + 11 letras + "y") não é sobre "marcar uma caixinha por marcar". É sobre garantir que seu serviço Go não apague as luzes para 15% da população mundial. Neste artigo, vamos explorar como implementar acessibilidade em projetos Go sem fanatismo, mas com benefícios reais. Vamos nessa!
\n\nPor que acessibilidade em Go não é opcional, é padrão
\n\nGo é uma linguagem para backend, mas isso não significa que ela não participe da criação de uma interface acessível. Se você escreve APIs para o frontend, gera HTML no servidor ou cria utilitários CLI — você já impacta a acessibilidade. A má notícia: muitos desenvolvedores Go acham que "a11y é problema do frontend". A boa notícia: você pode corrigir isso em uma tarde.
\n\nO que é acessibilidade web do ponto de vista do Go?
\n\nAcessibilidade web (web accessibility) é a capacidade de um site ou aplicativo ser usado por pessoas com diferentes limitações: visão, audição, mobilidade, habilidades cognitivas. No contexto do Go, isso significa:
\n\n- \n
- Marcação HTML correta gerada pelo servidor (por exemplo, via
html/template); \n - Atributos ARIA corretos para conteúdo dinâmico; \n
- Navegação lógica pelo teclado; \n
- Mensagens de erro claras (não "Erro 500", mas "Não foi possível salvar o arquivo: espaço insuficiente"). \n
E sim, Go é a linguagem ideal para isso. Sua tipagem forte e ferramentas integradas permitem verificar templates em tempo real. Mas vamos por partes.
\n\nMarcação semântica: o alicerce da acessibilidade em Go
\n\nQuando você gera HTML via html/template, você é o arquiteto da interface. Se seu código joga <div> em cada botão, os leitores de tela (screen readers) não entenderão o que é aquele elemento. Mas se você usar <button>, eles dirão: "Botão. Pressione para enviar o formulário".
Exemplo: formulário acessível em Go
\n\nSuponha que você esteja escrevendo um formulário de cadastro. Versão ruim:
\n\n// Ruim: sem semântica\ntmpl := `<div class="form">\n <div>Nome</div>\n <input type="text" id="name">\n <div class="error">{{.NameError}}</div>\n</div>`\n\n\nVersão boa — com <label> e aria-describedby:
// Bom: marcação semântica + ARIA\ntmpl := `<form>\n <label for="name">Nome</label>\n <input type="text" id="name" aria-describedby="name-error">\n <span id="name-error" role="alert">{{if .NameError}}{{.NameError}}{{end}}</span>\n</form>`\n\n\nO que mudou? O leitor de tela agora sabe: isso é um formulário, o campo de entrada está vinculado a um rótulo e o erro é um alerta. O usuário ouvirá: "Nome. Editar texto. Erro: campo obrigatório".
\n\nAtributos ARIA: quando o HTML não é suficiente
\n\nÀs vezes, as tags padrão não são suficientes. Por exemplo, você está criando abas (tabs) em Go + HTMX. Sem ARIA, elas soarão como "link, link, link...". Com ARIA, soarão como "Aba 1, selecionada. Aba 2. Aba 3".
\n\nComo adicionar ARIA em templates Go
\n\nOs atributos ARIA são passados como atributos normais em HTML. Aqui está um exemplo para abas:
\n\n<div role="tablist" aria-label="Configurações do perfil">\n <button role="tab" aria-selected="{{if eq .Tab "profile"}}true{{else}}false{{end}}" \n aria-controls="panel-profile" id="tab-profile">Perfil</button>\n <button role="tab" aria-selected="{{if eq .Tab "security"}}true{{else}}false{{end}}" \n aria-controls="panel-security" id="tab-security">Segurança</button>