Todas as atividades
Exibição Visual

Acordeão

Apresenta conteúdo em seções expansíveis. O aprendiz clica em cada item para revelar o texto oculto, controlando o ritmo da leitura e evitando sobrecarga de informação.

Conhecimento e compreensão acordeão expansível conteúdo accordion

Experimente

Camadas da Terra

É a camada mais externa e fina do planeta, onde vivemos. Varia de 5 km (sob os oceanos) a 70 km (sob as montanhas) de espessura, e é dividida em placas tectônicas que se movem lentamente ao longo do tempo geológico.

Camada intermediária, com quase 2.900 km de espessura, composta por rocha em estado semi-sólido que se movimenta em correntes de convecção — esse movimento é o que empurra as placas tectônicas na superfície.

A camada mais interna, dividida em núcleo externo (líquido, de ferro e níquel) e núcleo interno (sólido, sob pressão extrema). O movimento do núcleo externo gera o campo magnético que protege o planeta.

Código-fonte

PHP

Dados de exemplo

Cada item tem um título curto (o que a pessoa vê antes de clicar) e o conteúdo, que só aparece depois.

1 <?php
2 $itens = [
3 ['titulo' => 'Sono leve', 'conteudo' => 'Primeira fase do ciclo, transição entre acordado e dormindo. A respiração e os batimentos cardíacos começam a desacelerar, e a pessoa desperta fácil com qualquer estímulo.'],
4 ['titulo' => 'Sono profundo', 'conteudo' => 'Fase de recuperação física do corpo — os músculos relaxam ao máximo, a pressão arterial cai e o corpo libera hormônios de crescimento. É a fase mais difícil de interromper.'],
5 ['titulo' => 'Sono REM', 'conteudo' => 'Fase de maior atividade cerebral, onde ocorrem a maioria dos sonhos. Os olhos se movem rapidamente sob as pálpebras e o corpo fica temporariamente paralisado.'],
6 ];
7 ?>

Estrutura do item

Cada item tem dois níveis — ".item" (recebe a linha divisória entre um item e outro) envolvendo ".borda" (recebe a cor de destaque quando aberto). Ver o bloco "Cor de destaque" do CSS pra entender por que são dois níveis, não um só.

1 <div class="acordeao">
2 <?php foreach ($itens as $i => $item): $aberto = $i === 0; ?>
3 <div class="item">
4 <div class="borda<?= $aberto ? ' aberto' : '' ?>">
5 <button type="button" class="cabecalho" aria-expanded="<?= $aberto ? 'true' : 'false' ?>">
6 <span class="numero"><?= $i + 1 ?></span>
7 <span class="titulo"><?= htmlspecialchars($item['titulo']) ?></span>
8 <span class="seta<?= $aberto ? ' girada' : '' ?>">&#9662;</span>
9 </button>
10 <div class="conteudo<?= $aberto ? ' expandido' : '' ?>">
11 <div class="conteudo-interno">
12 <p class="texto"><?= htmlspecialchars($item['conteudo']) ?></p>
13 </div>
14 </div>
15 </div>
16 </div>
17 <?php endforeach; ?>
18 </div>
CSS

Cartão

Contêiner geral do acordeão.

1 .acordeao {
2 border: 1px solid #e2e8f0;
3 border-radius: 12px;
4 overflow: hidden;
5 font-family: inherit;
6 }

Divisória entre itens

Usa border-top (não o atalho "border") pra nunca colidir com a cor de destaque do item aberto, que fica num elemento diferente e usa border-left. Misturar os dois na mesma propriedade é a receita de uma cor apagar a outra.

1 .item + .item {
2 border-top: 1px solid #e2e8f0;
3 }

Cor de destaque do item aberto

Mora num filho do item (.borda), não no próprio .item — separar os dois níveis evita qualquer disputa de especificidade entre a linha divisória de cima e a cor lateral, mesmo que uma das duas regras mude no futuro.

1 .borda {
2 border-left: 4px solid transparent;
3 transition: border-color 0.2s ease, background-color 0.2s ease;
4 }
5 .borda.aberto {
6 border-left-color: #6366f1;
7 background: rgba(99, 102, 241, 0.06);
8 }

Cabeçalho clicável

Número, título e seta numa linha só; toda a largura é clicável, não só o texto.

1 .cabecalho {
2 width: 100%;
3 display: flex;
4 align-items: center;
5 gap: 12px;
6 padding: 16px 20px;
7 border: none;
8 background: none;
9 text-align: left;
10 font: inherit;
11 cursor: pointer;
12 }
13 .cabecalho:hover {
14 background: rgba(99, 102, 241, 0.04);
15 }
16 .cabecalho:focus-visible {
17 outline: 2px solid #6366f1;
18 outline-offset: -2px;
19 }
20
21 .numero {
22 flex-shrink: 0;
23 width: 24px;
24 height: 24px;
25 border-radius: 999px;
26 background: #f1f5f9;
27 color: #64748b;
28 font-size: 12px;
29 font-weight: 700;
30 display: flex;
31 align-items: center;
32 justify-content: center;
33 }
34
35 .titulo {
36 flex: 1;
37 font-weight: 600;
38 font-size: 14px;
39 color: #1e293b;
40 }
41
42 .seta {
43 flex-shrink: 0;
44 color: #64748b;
45 transition: transform 0.2s ease;
46 }
47 .seta.girada {
48 transform: rotate(180deg);
49 }

Conteúdo revelado

grid-template-rows de 0fr pra 1fr anima a altura sem precisar medir pixel em JS — funciona pra qualquer tamanho de texto, sem cortar conteúdo grande nem deixar curto demais parecendo instantâneo.

1 .conteudo {
2 display: grid;
3 grid-template-rows: 0fr;
4 transition: grid-template-rows 0.2s ease-in-out;
5 }
6 .conteudo.expandido {
7 grid-template-rows: 1fr;
8 }
9 .conteudo-interno {
10 overflow: hidden;
11 }
12 .texto {
13 margin: 0;
14 padding: 0 20px 16px 56px;
15 font-size: 14px;
16 line-height: 1.6;
17 color: #475569;
18 }
JavaScript

Encontrar os itens

Localiza cada item do acordeão e guarda a lista inteira, pra poder fechar os outros quando um abre.

1 document.addEventListener('DOMContentLoaded', function () {
2 document.querySelectorAll('.acordeao').forEach(function (acordeao) {
3 var itens = acordeao.querySelectorAll('.item');

Trocar o estado de um item

Cabeçalho, seta, borda e conteúdo mudam juntos — nunca só uma parte, senão o visual e o aria-expanded saem de sincronia.

1 function aplicar(item, aberto) {
2 var borda = item.querySelector('.borda');
3 var cabecalho = item.querySelector('.cabecalho');
4 var seta = cabecalho.querySelector('.seta');
5 var conteudo = item.querySelector('.conteudo');
6
7 cabecalho.setAttribute('aria-expanded', aberto ? 'true' : 'false');
8 seta.classList.toggle('girada', aberto);
9 borda.classList.toggle('aberto', aberto);
10 conteudo.classList.toggle('expandido', aberto);
11 }

Abertura exclusiva

Ao abrir um item, todos os outros fecham primeiro — só um fica visível de cada vez. É isso que faz o acordeão controlar o ritmo da leitura; permitir vários abertos ao mesmo tempo vira só um bloco de texto comum.

1 itens.forEach(function (item) {
2 var cabecalho = item.querySelector('.cabecalho');
3 cabecalho.addEventListener('click', function () {
4 var estavaAberto = cabecalho.getAttribute('aria-expanded') === 'true';
5 itens.forEach(function (outro) { if (outro !== item) aplicar(outro, false); });
6 aplicar(item, !estavaAberto);
7 });
8 });