Lista de perguntas separadas por régua, cada uma abrindo em altura animada. O sinal à direita é um + cuja barra vertical gira 90° e vira −. Um item aberto por vez.
Quando usar
- Antes do rodapé, depois do CTA principal. É onde o visitante que quase converteu vai buscar a objeção que falta.
- 5 a 10 perguntas.
- Quando as perguntas são objeções reais — as que aparecem na primeira reunião comercial.
Quando não usar
- Como central de ajuda. Acima de ~12 itens, o acordeão vira parede e o visitante precisa de busca.
- Para esconder informação que deveria estar na página. FAQ não é depósito do que não coube.
- Quando o SEO depende do conteúdo estar visível: o texto existe no HTML, mas o padrão de leitura muda.
Padrão editorial
| Slot | Regra |
|---|---|
| Pergunta | Escrita na voz do cliente, na primeira pessoa: "Qual é o investimento inicial necessário?", não "Investimento mínimo". 6 a 12 palavras, uma linha só. |
| Resposta | 1 a 3 frases, 30 a 60 palavras, teto de 72ch. Responde direto na primeira frase; o resto é contexto. |
Ordem: da objeção mais comum para a mais rara. A primeira pergunta é quase sempre "como funciona" e a última é "como começo".
Nunca responda com "depende". Se depende, diga do quê e dê a faixa.
Como usar
<link rel="stylesheet" href="componentes/listas/acordeao-faq/estilo.css">
<script src="componentes/listas/acordeao-faq/script.js"></script>
Cada resposta precisa de id único, e a pergunta correspondente aponta para ele em aria-controls.
Variações
- Vários abertos ao mesmo tempo — remova o laço que fecha os irmãos no script.
- Primeiro item já aberto —
is-openno HTML e uma chamada deabrir()no init. Útil quando a primeira pergunta é a que mais converte. - Com cartão de contato — as perguntas dividem a dobra com um cartão ao lado: "Não achou a sua pergunta?", uma frase e dois botões. Quem chega ao fim do FAQ sem resposta é exatamente quem converteria por contato. O cartão é
stickye acompanha a leitura; abaixo de 860px desce para baixo das perguntas. O markup completo está nopreview-extra.html:
<div class="faq-duo">
<div class="faq" data-faq>…os itens…</div>
<aside class="faq-cartao" aria-label="Fale com a gente">
<p class="faq-cartao-t">Não achou a sua pergunta?</p>
<p class="faq-cartao-p">Um sócio responde por escrito em até um dia útil.</p>
<div class="faq-cartao-acoes">
<a class="btn btn-primary" href="#agendar">Agendar</a>
<a class="btn btn-ghost" href="mailto:contato@exemplo.invalid">Escrever</a>
</div>
</aside>
</div>
Referência visual: ruul.io (via cta.gallery), 2026-09-29.
Gotchas
- A pergunta é
<button>, não<div>com clique. Teclado, foco e leitor de tela dependem disso. Oaria-expandedé o que anuncia "recolhido/expandido". max-heighté medido no clique, não no load. Se a fonte ainda não tinha carregado quando a página montou, a altura calculada estaria errada e a resposta sairia cortada.- Não dá para animar
height:auto. Emax-heightchutado alto (tipo999px) faz a abertura parecer lenta e o fechamento ter atraso, porque a transição percorre a distância inteira. - O
resizerecalcula o item aberto. Mudar a largura da janela muda a altura do texto; sem isso omax-heightcongelado corta a resposta. - O sinal gira, não troca. Duas pseudo-barras onde a vertical rotaciona 90°. Trocar um ícone por outro piscaria.
- O cartão da variação é
stickydentro de um[data-rv], e funciona. Filtro prende descendentefixed, nãosticky(MANUAL §5, precedentelistas/tabela-comparativa). max-width:840px, não a coluna inteira. Linha de resposta acima de ~75 caracteres cansa, e a pergunta centralizada precisa de bloco mais estreito para não ficar solta.
Histórico
| Projeto | Onde | Data | Diferenças |
|---|---|---|---|
| Liberta Wealth | index.html #duvidas |
2026-08 | Origem, com 8 perguntas. Classes .faq-i, .faq-q, .faq-a, .pm, estado .open, script varrendo .faq-i global, sem nenhum atributo ARIA, sem recálculo no resize. |
Normalizações aplicadas na extração: .faq-i → .faq-item, .faq-q → .faq-question, .faq-a → .faq-answer, .pm → .faq-sign; .open → .is-open; script passou a partir de [data-faq], suportando vários acordeões na página; adicionados aria-expanded, aria-controls e role="region"; adicionado recálculo de altura no resize; adicionado prefers-reduced-motion.