Como criar um acordeão usando somente HTML
TL;DR
O HTML5 introduziu um elemento chamado Details (representado pela tag <details>
) que cria um elemento de interação (widget) que revela a informação incluída dentro desse elemento quando a interação do usuário determina que ele seja aberto. Segundo a tabela de compatibilidade do MDN, apenas o Internet Explorer não oferece suporte a esse recurso — todos os outros navegadores (móveis ou não) são compatíveis.
Aqui uma demonstração de como esse elemento funciona
Todo texto colocado dentro da tag <summary>
dentro da tag <details>
será renderizado como o único texto a ser exibido sem qualquer interação do usuário. O restante do texto, fora da tag <summary>
mas dentro da tag <details>
, será considerado o conteúdo a ser exibido ou ocultado ou após a interação do usuário.
Como eu descobri isso?
Recentemente eu incluí no tema que uso em meus dois blogs um pequeno elemento que exibe o índice de cada postagem publicada. O código incluído nada mais é do que uma caixa de seleção que, ao ser clicada ou tocada pelo usuário, exibe uma lista de todos os cabeçalhos principais do texto. Considerando experiências anteriores observando o código de outras pessoas, eu acreditava que esse tipo de elemento só poderia ser criado através de um artifício como o que eu usei ou ao usar Javascript (o que tendo a evitar para respeitar os hábitos de navegação de pessoas que ativamente bloqueiam a execução desse tipo de script). Mas uma postagem no fediverso de @cypnk@mastodon.social mencionando a tag acabou chamando a minha atenção:
FYI You can nest <details> tags within <ul> and vice versa to create a collapsible tree menu without JS or CSS
E.G.
<details>
<summary>Root</summary>
<ul>
<li>
<details>
<summary>Sub</summary>
<ul><li>etc...</li></ul>
</details>
</li>
</ul>
</details>
Conferindo a documentação sobre o elemento no MDN, eu me surpreendi com como quase todos os navegadores mais usados oferecem suporte à funcionalidade.
Limitações
Digo quase porque infelizmente o Internet Explorer não oferece suporte a esse elemento. Segundo um comentário em uma postagem do CSS Tricks sobre o assunto, esse elemento aparecerá como inline no navegador, “posicionado desajeitadamente em um parágrafo único”. A pessoa ainda acrescenta que adicionar display: block
às tags <summary>
e <details>
em seu CSS fará com que elas sejam exibidas uma em cima da outra, como se esperaria para manter o mínimo de sua organização original.