Um acordeão costuma nascer como solução para uma página comprida. As perguntas frequentes viram linhas compactas, o conteúdo cabe melhor no celular e a interface parece mais limpa. O problema aparece quando essa economia visual esconde informação demais, transforma títulos em div clicável ou deixa o estado aberto conhecido apenas pela rotação de um ícone.

Um acordeão acessível mantém a estrutura do conteúdo mesmo fechado. Cada cabeçalho precisa ser um controle com nome e estado, a resposta associada deve entrar e sair da leitura junto com a apresentação visual, e a interação precisa funcionar por teclado, toque e leitor de tela. Este guia cobre a escolha do padrão, duas implementações possíveis e o reteste da página publicada.

Confirme se esconder o conteúdo ajuda

Não comece pelo componente. Comece pela leitura. Acordeões funcionam bem quando cada seção pode ser entendida de forma independente e a pessoa já sabe qual título quer abrir. Perguntas frequentes, detalhes opcionais e etapas de configuração são casos comuns.

Mantenha o conteúdo visível quando:

  • as seções precisam ser comparadas lado a lado;
  • a resposta contém informação essencial para decidir ou converter;
  • quase todas as pessoas precisam abrir quase todos os itens;
  • o título sozinho não permite prever o que está escondido;
  • a busca do navegador precisa encontrar e mostrar o trecho sem depender de script;
  • imprimir ou salvar a página deve preservar todo o conteúdo.

Uma lista de títulos e parágrafos pode ser mais útil do que uma interface compacta. O HTML Standard também alerta que limitar um grupo para apenas um painel aberto pode atrapalhar quem quer comparar respostas. Escolha exclusividade por necessidade, não por hábito visual.

Diferencie acordeão de abas e menu

No padrão de acordeão da W3C, cabeçalhos empilhados mostram ou escondem os painéis correspondentes. Cada cabeçalho continua na ordem normal da página. Tab visita os controles e qualquer elemento interativo dentro dos painéis abertos.

Abas são um componente composto. Apenas a aba ativa entra na sequência de Tab, enquanto setas movem o foco dentro do conjunto. Um menu organiza ações ou navegação, não seções extensas da mesma página. Não aplique role="tab" ou role="menuitem" a uma lista de perguntas só porque o visual se parece com outro componente.

Para uma única seção expansível, o nome mais preciso é disclosure. O padrão de disclosure da W3C usa um botão, aria-expanded e, opcionalmente, aria-controls. Um acordeão reúne vários desses controles e pode acrescentar uma hierarquia de títulos.

Prefira details e summary quando bastarem

O HTML nativo resolve muitos casos sem JavaScript:

<details>
<summary>Posso usar meu próprio domínio?</summary>
<p>Sim. Conecte o domínio ao Site e conclua a verificação indicada no painel.</p>
</details>

O navegador oferece foco, ativação por teclado e estado aberto ou fechado. O conteúdo de summary funciona como rótulo do controle. Use texto que antecipe a resposta, não expressões repetidas como “Saiba mais”.

O atributo booleano open define o estado inicial. open="false" ainda abre o painel, porque a presença do atributo é o que conta. Para começar fechado, remova o atributo.

É possível atribuir o mesmo name a vários elementos details para formar um grupo exclusivo, no qual abrir um fecha os outros:

<details name="faq-publicacao">
<summary>Quanto tempo leva para publicar?</summary>
<p>...</p>
</details>
<details name="faq-publicacao">
<summary>Posso republicar na mesma URL?</summary>
<p>...</p>
</details>

Use esse comportamento apenas quando manter múltiplas respostas abertas não trouxer benefício. Teste a combinação de navegadores e tecnologias assistivas prevista para o produto. O elemento nativo reduz código, mas não substitui a validação do resultado.

Monte um acordeão customizado com botões reais

Quando o design ou o controle de estado exige uma implementação própria, cada cabeçalho precisa conter um button. Relacione o controle ao painel e mantenha aria-expanded sincronizado com a visibilidade.

<h3>
<button
type="button"
id="pergunta-dominio"
aria-expanded="false"
aria-controls="resposta-dominio"
>
Posso usar meu próprio domínio?
</button>
</h3>
<div id="resposta-dominio" aria-labelledby="pergunta-dominio" hidden>
<p>Sim. Conecte o domínio ao Site e conclua a verificação indicada no painel.</p>
</div>

Ao abrir, o script deve mudar aria-expanded para true e remover hidden. Ao fechar, deve fazer o inverso. Não mantenha um painel visualmente fechado disponível para leitor de tela ou para foco. Também não esconda com opacity: 0 um bloco que ainda contém links alcançáveis.

O nível do título deve seguir a arquitetura da página. Não escolha h3 só porque o exemplo usa esse nível. Se o acordeão estiver logo abaixo do h2 “Perguntas frequentes”, cada pergunta pode ser h3. O guia sobre títulos e regiões ajuda a revisar essa hierarquia.

Mantenha o teclado simples

Um botão nativo já responde a Enter e Espaço. Tab e Shift+Tab seguem a ordem normal entre cabeçalhos e controles dos painéis abertos. Não crie uma segunda implementação de teclado para repetir esse comportamento.

As setas para mover entre cabeçalhos são opcionais no padrão de acordeão. Se você as implementar, preserve também a navegação normal com Tab e teste início, fim e repetição. Uma FAQ curta raramente precisa dessa camada extra.

Evite:

  • div ou span com listener de clique;
  • tabindex positivo para forçar uma ordem;
  • abrir a seção apenas com hover;
  • mover foco automaticamente para o primeiro link do painel;
  • fechar uma resposta quando o foco sai dela;
  • usar o ícone como único indicador de estado.

O artigo sobre navegação por teclado traz um roteiro para ordem, foco visível, armadilhas e conteúdo encoberto.

Mostre estado sem depender de uma seta

O estado programático mora em aria-expanded. O estado visual pode usar ícone, borda, peso e espaçamento, mas precisa continuar perceptível sem cor e em alto contraste.

Se houver um ícone decorativo, esconda-o da árvore de acessibilidade. Não deixe o leitor de tela anunciar “mais” ou o nome de um arquivo SVG depois do título. Faça o ícone acompanhar o atributo do botão, em vez de manter um estado visual separado no JavaScript.

O rótulo geralmente deve permanecer estável. Um botão chamado “Quais formas de pagamento?” pode comunicar expandido ou recolhido por aria-expanded; não precisa trocar para “Fechar quais formas de pagamento?”. Textos dinâmicos são úteis quando a ação não fica clara apenas pelo estado, mas criam mais pontos para sincronizar e testar.

Decida se os painéis são regiões

O padrão da W3C permite usar role="region" com aria-labelledby nos painéis. Isso pode ajudar quando um painel contém subtítulos ou outro acordeão. Aplicar região a cada resposta curta de uma FAQ, porém, enche a navegação por landmarks sem acrescentar contexto.

Use regiões com moderação. O conteúdo já pode ter estrutura suficiente por meio de títulos, listas e parágrafos. ARIA não compensa HTML vazio.

O guia sobre nomes acessíveis de links e botões ajuda a conferir o texto anunciado de cada cabeçalho e dos controles que aparecem dentro do painel.

Preserve conteúdo, URL e estado útil

Abrir um painel não costuma exigir mudança de foco. A pessoa ativou o botão e sabe onde está. Manter o foco ali facilita fechar a seção ou seguir para a próxima pergunta.

Há casos em que o estado precisa sobreviver a outra ação:

  • um link direto aponta para uma pergunta específica;
  • a validação de um formulário revela um painel com erro;
  • voltar pelo histórico deveria restaurar a seção aberta;
  • a busca interna leva a um trecho escondido;
  • uma preferência do usuário controla a expansão.

Defina esse contrato antes de codificar. Se um hash identifica o painel, abra a seção correspondente e garanta que o destino fique visível sem esconder o foco sob um cabeçalho fixo. Se JavaScript falhar, o conteúdo essencial deve continuar acessível.

Teste conteúdo real em largura real

Substitua frases curtas de demonstração por perguntas e respostas finais. Depois teste:

  • títulos que quebram em duas ou três linhas;
  • resposta com lista, link e formulário;
  • zoom de 200% e 400%;
  • largura equivalente a 320 pixels CSS;
  • toque perto das bordas do controle;
  • foco visível sobre todos os estados;
  • várias seções abertas;
  • primeira e última pergunta;
  • JavaScript lento ou indisponível.

O cabeçalho inteiro pode ser a área clicável, desde que elementos persistentes como menus de ação não fiquem aninhados dentro do botão. O mínimo de alvo e espaçamento continua valendo. Use o roteiro de alvos de toque para medir o componente renderizado.

Valide com leitor de tela

Um scanner pode encontrar aria-controls quebrado, botão sem nome ou conteúdo focável sob hidden. Ele não confirma que os títulos são compreensíveis, que o conjunto não ficou cansativo ou que o estado é anunciado no momento certo.

Faça um percurso manual:

  1. navegue pelos cabeçalhos com teclado;
  2. escute nome, função e estado de cada controle;
  3. abra e feche com Enter e Espaço;
  4. leia todo o conteúdo revelado;
  5. percorra links e campos internos;
  6. feche o painel e confirme que o conteúdo saiu da leitura e do foco;
  7. repita com mais de uma seção aberta, quando permitido;
  8. teste a mesma tarefa em tela estreita.

O guia de teste com leitor de tela ajuda a separar falha do componente, configuração da tecnologia assistiva e atalho do navegador.

Peça uma correção que possa ser conferida

Revise os acordeões e disclosures desta landing page sem publicar ainda.
Escopo:
- fonte e commit: [referência]
- rotas: [lista]
- conjuntos expansíveis: [inventário]
Para cada conjunto:
1. Confirme se o conteúdo deveria ficar recolhido.
2. Registre título, controle, painel, estado inicial e regra de exclusividade.
3. Prefira details e summary quando o HTML nativo atender ao comportamento.
4. Em componentes customizados, sincronize aria-expanded, aria-controls e hidden.
5. Preserve a ordem de foco e remova controles de painéis fechados da navegação.
6. Teste teclado, leitor de tela, toque, zoom e JavaScript indisponível.
7. Preserve texto, links, tracking e lógica de negócio.
Entregue o inventário, o diff e as evidências antes de publicar.

O pedido dá ao agente uma fronteira verificável. Ele não autoriza reescrever respostas, trocar a arquitetura da página ou esconder conteúdo para caber no layout.

Reteste depois de publicar

Depois da aprovação, siga a documentação de Publicação: publique uma nova Version, acompanhe o deploy e abra a URL final. Repita o roteiro com teclado e leitor de tela no HTML servido.

Confira também busca, links profundos, analytics e formulários dentro dos painéis. Se a build, a hidratação ou um script de terceiros separar o estado visual do estado acessível, corrija a fonte e republique o mesmo Site. O acordeão está pronto quando o conteúdo continua compreensível, operável e encontrável, aberto ou fechado.