Cartões de Memorização
Cards digitais com frente e verso: o aprendiz vê a frente (pergunta/conceito), tenta lembrar, e vira para ver o verso (resposta/definição). Usa o princípio de recuperação ativa e revisão espaçada.
Experimente
Elementos e Conceitos de Química
1/4Tente lembrar antes de virar →
Qual é o elemento mais abundante na atmosfera terrestre?
Código-fonte
Dados de exemplo
Quatro cartões fixos, embaralhados a cada carregamento da página.
| 1 |
<?php
|
| 2 |
$titulo = 'Capitais do Mundo';
|
| 3 |
$cartoes = [
|
| 4 |
['frente' => 'Qual é a capital da Austrália?', 'verso' => 'Camberra — não Sydney, que é só a maior cidade do país.'],
|
| 5 |
['frente' => 'Qual é a capital do Canadá?', 'verso' => 'Ottawa — não Toronto, que é só a maior cidade.'],
|
| 6 |
['frente' => 'Qual é a capital da Turquia?', 'verso' => 'Ancara — não Istambul, que é só a maior cidade.'],
|
| 7 |
['frente' => 'Qual é a capital do Brasil?', 'verso' => 'Brasília — inaugurada em 1960, no lugar do Rio de Janeiro.'],
|
| 8 |
];
|
| 9 |
shuffle($cartoes);
|
| 10 |
?>
|
Título e cartões
Cada cartão junta frente e verso; só o primeiro começa visível, sempre virado pra frente.
| 1 |
<div class="flashcards" data-tipo="flashcards" data-titulo="<?= htmlspecialchars($titulo) ?>">
|
| 2 |
|
| 3 |
<div class="flashcards-cabecalho">
|
| 4 |
<p><?= htmlspecialchars($titulo) ?></p>
|
| 5 |
<span class="flashcards-posicao">1/<?= count($cartoes) ?></span>
|
| 6 |
</div>
|
| 7 |
|
| 8 |
<div class="flashcards-corpo">
|
| 9 |
<?php foreach ($cartoes as $i => $cartao): ?>
|
| 10 |
<div class="flashcards-card<?= $i > 0 ? ' escondido' : '' ?>" data-indice="<?= $i ?>">
|
| 11 |
<div class="flashcards-frente" data-virado="false">
|
| 12 |
<p class="flashcards-dica">Tente lembrar antes de virar →</p>
|
| 13 |
<p class="flashcards-pergunta"><?= htmlspecialchars($cartao['frente']) ?></p>
|
| 14 |
</div>
|
| 15 |
<div class="flashcards-verso escondido">
|
| 16 |
<p class="flashcards-dica">Resposta</p>
|
| 17 |
<p class="flashcards-resposta"><?= htmlspecialchars($cartao['verso']) ?></p>
|
| 18 |
</div>
|
| 19 |
</div>
|
| 20 |
<?php endforeach; ?>
|
Progresso, virar e navegação
A barra é clicável (pula direto pro cartão); "Anterior"/"Próximo" sempre voltam o cartão de destino pra frente.
| 1 |
<div class="flashcards-progresso">
|
| 2 |
<?php foreach ($cartoes as $i => $cartao): ?>
|
| 3 |
<button type="button" class="flashcards-barra" data-estado="<?= $i === 0 ? 'ativo' : 'inativo' ?>" data-indice="<?= $i ?>"></button>
|
| 4 |
<?php endforeach; ?>
|
| 5 |
</div>
|
| 6 |
|
| 7 |
<button type="button" class="flashcards-virar">Virar</button>
|
| 8 |
|
| 9 |
<div class="flashcards-nav">
|
| 10 |
<button type="button" class="flashcards-anterior" disabled>← Anterior</button>
|
| 11 |
<button type="button" class="flashcards-proximo">Próximo →</button>
|
| 12 |
</div>
|
| 13 |
</div>
|
| 14 |
|
| 15 |
</div>
|
Card e cabeçalho
Contêiner geral e a caixa de título centralizada.
| 1 |
.flashcards {
|
| 2 |
max-width: 420px;
|
| 3 |
border: 1px solid #e2e8f0;
|
| 4 |
border-radius: 16px;
|
| 5 |
background: #fff;
|
| 6 |
font-family: sans-serif;
|
| 7 |
overflow: hidden;
|
| 8 |
}
|
| 9 |
|
| 10 |
.flashcards-cabecalho {
|
| 11 |
padding: 20px 24px;
|
| 12 |
border-bottom: 1px solid #cbd5e1;
|
| 13 |
background: rgba(241, 245, 249, .6);
|
| 14 |
text-align: center;
|
| 15 |
}
|
| 16 |
|
| 17 |
.flashcards-cabecalho p {
|
| 18 |
margin: 0;
|
| 19 |
font-weight: 700;
|
| 20 |
font-size: 18px;
|
| 21 |
color: #0f172a;
|
| 22 |
}
|
| 23 |
|
| 24 |
.flashcards-posicao {
|
| 25 |
display: inline-block;
|
| 26 |
margin-top: 6px;
|
| 27 |
font-size: 12px;
|
| 28 |
font-family: monospace;
|
| 29 |
color: #64748b;
|
| 30 |
}
|
| 31 |
|
| 32 |
.flashcards-corpo { padding: 20px; }
|
| 33 |
.flashcards-card.escondido { display: none; }
|
Frente e verso do cartão
Cores diferentes por estado — indigo para a pergunta, roxo para a resposta — pra nunca confundir qual lado está visível.
| 1 |
.flashcards-frente,
|
| 2 |
.flashcards-verso {
|
| 3 |
min-height: 120px;
|
| 4 |
padding: 24px;
|
| 5 |
border-radius: 16px;
|
| 6 |
border: 2px solid;
|
| 7 |
text-align: center;
|
| 8 |
display: flex;
|
| 9 |
flex-direction: column;
|
| 10 |
align-items: center;
|
| 11 |
justify-content: center;
|
| 12 |
cursor: pointer;
|
| 13 |
}
|
| 14 |
|
| 15 |
.flashcards-frente { border-color: rgba(99, 102, 241, .3); background: rgba(99, 102, 241, .04); }
|
| 16 |
.flashcards-verso { border-color: rgba(168, 85, 247, .3); background: rgba(168, 85, 247, .04); }
|
| 17 |
.flashcards-verso.escondido { display: none; }
|
| 18 |
|
| 19 |
.flashcards-dica {
|
| 20 |
margin: 0 0 10px;
|
| 21 |
font-size: 11px;
|
| 22 |
font-weight: 700;
|
| 23 |
text-transform: uppercase;
|
| 24 |
letter-spacing: .04em;
|
| 25 |
}
|
| 26 |
|
| 27 |
.flashcards-frente .flashcards-dica { color: #4f46e5; }
|
| 28 |
.flashcards-verso .flashcards-dica { color: #9333ea; }
|
| 29 |
|
| 30 |
.flashcards-pergunta { margin: 0; font-weight: 600; color: #0f172a; }
|
| 31 |
.flashcards-resposta { margin: 0; color: #334155; line-height: 1.5; }
|
Progresso clicável, virar e navegação
A barra segmentada funciona como as bolinhas de um carrossel — cada segmento pula direto pro cartão correspondente.
| 1 |
.flashcards-progresso {
|
| 2 |
display: flex;
|
| 3 |
gap: 4px;
|
| 4 |
margin: 16px 0;
|
| 5 |
}
|
| 6 |
|
| 7 |
.flashcards-barra {
|
| 8 |
flex: 1;
|
| 9 |
height: 6px;
|
| 10 |
border: none;
|
| 11 |
border-radius: 999px;
|
| 12 |
padding: 0;
|
| 13 |
cursor: pointer;
|
| 14 |
}
|
| 15 |
|
| 16 |
.flashcards-barra[data-estado="inativo"] { background: #e2e8f0; }
|
| 17 |
.flashcards-barra[data-estado="ativo"] { background: #6366f1; }
|
| 18 |
|
| 19 |
.flashcards-virar {
|
| 20 |
display: block;
|
| 21 |
width: 100%;
|
| 22 |
padding: 10px 16px;
|
| 23 |
margin-bottom: 12px;
|
| 24 |
border: 1px solid rgba(99, 102, 241, .3);
|
| 25 |
border-radius: 10px;
|
| 26 |
background: rgba(99, 102, 241, .1);
|
| 27 |
color: #4338ca;
|
| 28 |
font: inherit;
|
| 29 |
font-weight: 600;
|
| 30 |
cursor: pointer;
|
| 31 |
}
|
| 32 |
|
| 33 |
.flashcards-nav {
|
| 34 |
display: flex;
|
| 35 |
justify-content: center;
|
| 36 |
gap: 12px;
|
| 37 |
}
|
| 38 |
|
| 39 |
.flashcards-anterior,
|
| 40 |
.flashcards-proximo {
|
| 41 |
padding: 8px 14px;
|
| 42 |
border: 1px solid #cbd5e1;
|
| 43 |
border-radius: 8px;
|
| 44 |
background: #f1f5f9;
|
| 45 |
font: inherit;
|
| 46 |
font-size: 13px;
|
| 47 |
cursor: pointer;
|
| 48 |
}
|
| 49 |
|
| 50 |
.flashcards-anterior:disabled,
|
| 51 |
.flashcards-proximo:disabled { opacity: .4; cursor: not-allowed; }
|
Trocar de cartão
Sempre volta o cartão de destino pra frente — nunca deixa a resposta de um cartão novo já visível.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
var raiz = document.querySelector('[data-tipo="flashcards"]');
|
| 3 |
var cartoes = raiz.querySelectorAll('.flashcards-card');
|
| 4 |
var barras = raiz.querySelectorAll('.flashcards-barra');
|
| 5 |
var posicao = raiz.querySelector('.flashcards-posicao');
|
| 6 |
var anterior = raiz.querySelector('.flashcards-anterior');
|
| 7 |
var proximo = raiz.querySelector('.flashcards-proximo');
|
| 8 |
var total = cartoes.length;
|
| 9 |
var atual = 0;
|
| 10 |
var virados = {};
|
| 11 |
var progressoEnviado = false;
|
| 12 |
|
| 13 |
function mostrarCartao(indice) {
|
| 14 |
cartoes[atual].classList.add('escondido');
|
| 15 |
barras[atual].dataset.estado = 'inativo';
|
| 16 |
|
| 17 |
atual = indice;
|
| 18 |
|
| 19 |
cartoes[atual].classList.remove('escondido');
|
| 20 |
barras[atual].dataset.estado = 'ativo';
|
| 21 |
posicao.textContent = (atual + 1) + '/' + total;
|
| 22 |
anterior.disabled = atual === 0;
|
| 23 |
proximo.disabled = atual === total - 1;
|
| 24 |
|
| 25 |
var frente = cartoes[atual].querySelector('.flashcards-frente');
|
| 26 |
var verso = cartoes[atual].querySelector('.flashcards-verso');
|
| 27 |
frente.classList.remove('escondido');
|
| 28 |
verso.classList.add('escondido');
|
| 29 |
frente.dataset.virado = 'false';
|
| 30 |
}
|
Virar e registrar progresso
Um Set improvisado (objeto) marca quais cartões já foram vistos; quando todos passam por ele, dispara o aviso de conclusão uma única vez.
| 1 |
function virar(cartao) {
|
| 2 |
var frente = cartao.querySelector('.flashcards-frente');
|
| 3 |
var verso = cartao.querySelector('.flashcards-verso');
|
| 4 |
var jaVirado = frente.dataset.virado === 'true';
|
| 5 |
|
| 6 |
frente.classList.toggle('escondido', !jaVirado);
|
| 7 |
verso.classList.toggle('escondido', jaVirado);
|
| 8 |
frente.dataset.virado = jaVirado ? 'false' : 'true';
|
| 9 |
|
| 10 |
if (!jaVirado) {
|
| 11 |
virados[cartao.dataset.indice] = true;
|
| 12 |
if (!progressoEnviado && Object.keys(virados).length >= total) {
|
| 13 |
progressoEnviado = true;
|
| 14 |
console.log('Progresso: todos os cartões foram revisados.');
|
| 15 |
}
|
| 16 |
}
|
| 17 |
}
|
| 18 |
|
| 19 |
raiz.querySelector('.flashcards-virar').addEventListener('click', function () {
|
| 20 |
virar(cartoes[atual]);
|
| 21 |
});
|
| 22 |
|
| 23 |
cartoes.forEach(function (cartao) {
|
| 24 |
cartao.querySelector('.flashcards-frente').addEventListener('click', function () {
|
| 25 |
virar(cartao);
|
| 26 |
});
|
| 27 |
});
|
| 28 |
|
| 29 |
anterior.addEventListener('click', function () {
|
| 30 |
if (atual > 0) mostrarCartao(atual - 1);
|
| 31 |
});
|
| 32 |
|
| 33 |
proximo.addEventListener('click', function () {
|
| 34 |
if (atual < total - 1) mostrarCartao(atual + 1);
|
| 35 |
});
|
| 36 |
|
| 37 |
barras.forEach(function (barra, i) {
|
| 38 |
barra.addEventListener('click', function () { mostrarCartao(i); });
|
| 39 |
});
|