Fazer um accordion onde só um item fica aberto por vez sempre exigiu JavaScript: escutar o clique em cada <details>, fechar todos os outros manualmente e torcer para não esquecer nenhum caso extra. Desde 2023 os navegadores suportam o atributo name no <details>, que agrupa vários elementos e faz o navegador cuidar da exclusividade sozinho — sem uma linha de script.
O jeito antigo
<details id="item1">
<summary>Pergunta 1</summary>
<p>Resposta 1</p>
</details>
<details id="item2">
<summary>Pergunta 2</summary>
<p>Resposta 2</p>
</details>
const itens = document.querySelectorAll('details');
itens.forEach((item) => {
item.addEventListener('toggle', () => {
if (item.open) {
itens.forEach((outro) => {
if (outro !== item) outro.open = false;
});
}
});
});
Funciona, mas é código só para replicar um comportamento que o próprio elemento já poderia oferecer nativamente.
Como funciona o atributo name
Basta dar o mesmo valor de name para os elementos <details> que devem se comportar como um grupo exclusivo:
<details name="faq">
<summary>Pergunta 1</summary>
<p>Resposta 1</p>
</details>
<details name="faq">
<summary>Pergunta 2</summary>
<p>Resposta 2</p>
</details>
<details name="faq">
<summary>Pergunta 3</summary>
<p>Resposta 3</p>
</details>
Ao abrir qualquer um deles, o navegador fecha automaticamente os demais que compartilham o mesmo name. Nenhum JavaScript é necessário, e o comportamento de teclado e acessibilidade do <details>/<summary> continua intacto.
Os elementos não precisam ser irmãos
O agrupamento é feito pelo valor de name, não pela posição no DOM. Isso permite espalhar os itens do grupo por lugares diferentes da página e ainda assim manter a exclusividade entre eles:
<section>
<details name="filtros">
<summary>Categoria</summary>
<p>Lista de categorias...</p>
</details>
</section>
<aside>
<details name="filtros">
<summary>Faixa de preço</summary>
<p>Slider de preço...</p>
</details>
</aside>
Estado inicial aberto
O atributo open continua funcionando normalmente dentro de um grupo. Se mais de um elemento do mesmo grupo vier marcado com open no HTML, o navegador fecha todos exceto o último:
<details name="faq" open>
<summary>Pergunta 1</summary>
<p>Resposta 1, aberta por padrão.</p>
</details>
<details name="faq">
<summary>Pergunta 2</summary>
<p>Resposta 2</p>
</details>
Estilizando o grupo
Nenhum CSS especial é exigido para o agrupamento funcionar, mas os seletores de sempre continuam disponíveis para dar cara de accordion à lista:
details[name="faq"] {
border-bottom: 1px solid #ddd;
}
details[name="faq"] summary {
cursor: pointer;
padding: 12px 0;
font-weight: 600;
list-style: none;
}
details[name="faq"] summary::-webkit-details-marker {
display: none;
}
details[name="faq"][open] summary {
color: #2563eb;
}
Quando usar
- FAQs onde só uma resposta deve ficar visível por vez.
- Painéis de filtro em que abrir um grupo fecha os outros para economizar espaço.
- Qualquer accordion "clássico" que hoje é montado com uma biblioteca de UI só por causa da exclusividade entre itens.
- Menus de navegação em abas expansíveis onde cada seção tem seus próprios subitens.
Cuidados
O agrupamento por name só afeta o comportamento de abrir/fechar; não existe nenhum evento novo disparado especificamente pelo agrupamento — o evento toggle de cada <details> continua disparando normalmente quando ele é aberto ou fechado, inclusive quando o fechamento acontece de forma automática por causa de outro item do grupo ter sido aberto. Vale também lembrar que o valor de name segue as mesmas regras de um atributo de formulário: evite espaços e escolha um nome que descreva o grupo, não o item individual.
Compatibilidade
O suporte já é bom nos navegadores modernos (Chrome, Edge e Safari desde o final de 2023, Firefox a partir da versão 130), mas vale conferir a tabela atualizada antes de depender dele como único mecanismo de um accordion crítico para a interface.
Conclusão
O atributo name no <details> transforma um padrão de UI muito comum — o accordion exclusivo — em algo puramente declarativo, eliminando o JavaScript que antes existia só para fechar os itens irmãos.
0 Comentário
Deixe seu Comentário!