Quebra-Cabeça Numérico
Apresenta expressões aritméticas com lacunas que o aprendiz deve completar. Desenvolve raciocínio matemático e fluência com operações numéricas.
Experimente
Complete a expressão preenchendo o número que falta:
Código-fonte
Dados de exemplo
Uma expressão com uma lacuna e a resposta esperada.
| 1 |
<?php
|
| 2 |
$instrucao = 'Complete a expressão preenchendo o número que falta:';
|
| 3 |
$expressao = '20% de 80 = ___';
|
| 4 |
$resposta = 16;
|
| 5 |
|
| 6 |
$partes = explode('___', $expressao);
|
| 7 |
?>
|
Expressão com o stepper embutido
O explode separa o texto nas marcas ___ e o stepper entra na emenda.
| 1 |
<div class="questao" data-tipo="quebra-cabeca-numerico" data-resposta="<?= $resposta ?>">
|
| 2 |
|
| 3 |
<p class="questao-instrucao"><?= htmlspecialchars($instrucao) ?></p>
|
| 4 |
|
| 5 |
<div class="questao-expressao">
|
| 6 |
<?php foreach ($partes as $i => $parte): ?>
|
| 7 |
<span><?= htmlspecialchars($parte) ?></span>
|
| 8 |
<?php if ($i < count($partes) - 1): ?>
|
| 9 |
<div class="questao-stepper" role="group" aria-label="Controle do valor">
|
| 10 |
<button type="button" class="questao-decrementar" aria-label="Diminuir valor">
|
| 11 |
<span aria-hidden="true">−</span>
|
| 12 |
</button>
|
| 13 |
<div class="questao-valor">
|
| 14 |
<input type="number" class="questao-input" aria-label="Valor da resposta"
|
| 15 |
placeholder="?" inputmode="numeric" autocomplete="off">
|
| 16 |
</div>
|
| 17 |
<button type="button" class="questao-incrementar" aria-label="Aumentar valor">
|
| 18 |
<span aria-hidden="true">+</span>
|
| 19 |
</button>
|
| 20 |
</div>
|
| 21 |
<?php endif; ?>
|
| 22 |
<?php endforeach; ?>
|
| 23 |
</div>
|
Área de ação
Reúne verificar, resultado e reiniciar numa caixa própria.
| 1 |
<div class="questao-acoes">
|
| 2 |
<button type="button" class="questao-verificar">Verificar</button>
|
| 3 |
|
| 4 |
<div class="questao-feedback" hidden></div>
|
| 5 |
|
| 6 |
<button type="button" class="questao-reset" hidden>Tentar novamente</button>
|
| 7 |
</div>
|
| 8 |
|
| 9 |
</div>
|
Expressão
Texto e stepper na mesma linha, quebrando naturalmente em telas estreitas.
| 1 |
.questao-expressao {
|
| 2 |
display: flex;
|
| 3 |
align-items: center;
|
| 4 |
justify-content: center;
|
| 5 |
flex-wrap: wrap;
|
| 6 |
gap: 8px;
|
| 7 |
font-family: monospace;
|
| 8 |
font-size: 20px;
|
| 9 |
margin-bottom: 24px;
|
| 10 |
}
|
Stepper
Três colunas — diminuir, valor, aumentar — sem depender do spinner nativo.
| 1 |
.questao-stepper {
|
| 2 |
display: grid;
|
| 3 |
grid-template-columns: 52px minmax(0, 1fr) 52px;
|
| 4 |
min-height: 56px;
|
| 5 |
overflow: hidden;
|
| 6 |
border: 2px solid #6366f1;
|
| 7 |
border-radius: 14px;
|
| 8 |
background: #f1f5f9;
|
| 9 |
transition: border-color .2s;
|
| 10 |
}
|
| 11 |
|
| 12 |
.questao-decrementar,
|
| 13 |
.questao-incrementar {
|
| 14 |
display: grid;
|
| 15 |
place-items: center;
|
| 16 |
background: rgba(99, 102, 241, .12);
|
| 17 |
color: #4338ca;
|
| 18 |
font-size: 24px;
|
| 19 |
font-weight: 700;
|
| 20 |
cursor: pointer;
|
| 21 |
}
|
| 22 |
|
| 23 |
.questao-decrementar:hover,
|
| 24 |
.questao-incrementar:hover { background: rgba(99, 102, 241, .25); }
|
| 25 |
.questao-decrementar:disabled,
|
| 26 |
.questao-incrementar:disabled { opacity: .4; cursor: not-allowed; }
|
| 27 |
|
| 28 |
.questao-valor {
|
| 29 |
display: flex;
|
| 30 |
align-items: center;
|
| 31 |
justify-content: center;
|
| 32 |
padding: 8px 12px;
|
| 33 |
border-inline: 1px solid rgba(99, 102, 241, .3);
|
| 34 |
}
|
| 35 |
|
| 36 |
.questao-input {
|
| 37 |
width: 6ch;
|
| 38 |
border: 0;
|
| 39 |
outline: 0;
|
| 40 |
background: transparent;
|
| 41 |
color: #4f46e5;
|
| 42 |
font-size: 20px;
|
| 43 |
font-weight: 700;
|
| 44 |
text-align: center;
|
| 45 |
}
|
Estados de correção
O próprio stepper muda de cor — a resposta é exata, não uma margem.
| 1 |
.questao-stepper.acerto { border-color: #16a34a; }
|
| 2 |
.questao-stepper.acerto .questao-input { color: #15803d; }
|
| 3 |
|
| 4 |
.questao-stepper.erro { border-color: #dc2626; }
|
| 5 |
.questao-stepper.erro .questao-input { color: #b91c1c; }
|
Área de ação
Separa os controles da expressão.
| 1 |
.questao-acoes {
|
| 2 |
display: flex;
|
| 3 |
flex-direction: column;
|
| 4 |
gap: 12px;
|
| 5 |
padding: 16px;
|
| 6 |
border: 1px solid #cbd5e1;
|
| 7 |
border-radius: 12px;
|
| 8 |
}
|
| 9 |
|
| 10 |
.questao-verificar,
|
| 11 |
.questao-reset {
|
| 12 |
width: 100%;
|
| 13 |
padding: 12px 16px;
|
| 14 |
border: none;
|
| 15 |
border-radius: 10px;
|
| 16 |
font: inherit;
|
| 17 |
font-weight: 600;
|
| 18 |
cursor: pointer;
|
| 19 |
}
|
| 20 |
|
| 21 |
.questao-verificar { background: #4f46e5; color: #fff; }
|
| 22 |
.questao-reset { background: #e5e7eb; color: #1f2937; }
|
| 23 |
|
| 24 |
.questao-feedback {
|
| 25 |
padding: 12px 16px;
|
| 26 |
border-radius: 10px;
|
| 27 |
line-height: 1.6;
|
| 28 |
}
|
| 29 |
|
| 30 |
.questao-feedback.acerto { background: #dcfce7; color: #14532d; }
|
| 31 |
.questao-feedback.erro { background: #fee2e2; color: #7f1d1d; }
|
| 32 |
.questao-feedback.aviso { background: #fef3c7; color: #78350f; }
|
Encontrar os elementos da questão
Localiza o stepper, os botões e a caixa de resultado.
| 1 |
document.addEventListener('DOMContentLoaded', function () {
|
| 2 |
document.querySelectorAll('.questao[data-tipo="quebra-cabeca-numerico"]').forEach(function (questao) {
|
| 3 |
var stepper = questao.querySelector('.questao-stepper');
|
| 4 |
var input = questao.querySelector('.questao-input');
|
| 5 |
var diminuir = questao.querySelector('.questao-decrementar');
|
| 6 |
var aumentar = questao.querySelector('.questao-incrementar');
|
| 7 |
var verificar = questao.querySelector('.questao-verificar');
|
| 8 |
var feedback = questao.querySelector('.questao-feedback');
|
| 9 |
var reset = questao.querySelector('.questao-reset');
|
| 10 |
var resposta = parseInt(questao.dataset.resposta, 10);
|
| 11 |
|
| 12 |
function valorAtual() {
|
| 13 |
var valor = parseInt(input.value, 10);
|
| 14 |
return Number.isNaN(valor) ? 0 : valor;
|
| 15 |
}
|
Incrementar e decrementar
Sem piso: a resposta de um quebra-cabeça pode ser negativa.
| 1 |
function alterarValor(delta) {
|
| 2 |
if (input.disabled) return;
|
| 3 |
input.value = valorAtual() + delta;
|
| 4 |
input.focus();
|
| 5 |
}
|
| 6 |
|
| 7 |
diminuir.addEventListener('click', function () { alterarValor(-1); });
|
| 8 |
aumentar.addEventListener('click', function () { alterarValor(1); });
|
Verificar a resposta
Compara o número exato e pinta o stepper conforme o resultado.
| 1 |
verificar.addEventListener('click', function () {
|
| 2 |
var val = parseInt(input.value, 10);
|
| 3 |
|
| 4 |
if (Number.isNaN(val)) {
|
| 5 |
feedback.className = 'questao-feedback aviso';
|
| 6 |
feedback.textContent = 'Digite um número antes de verificar.';
|
| 7 |
feedback.hidden = false;
|
| 8 |
return;
|
| 9 |
}
|
| 10 |
|
| 11 |
var correta = val === resposta;
|
| 12 |
input.disabled = true;
|
| 13 |
diminuir.disabled = true;
|
| 14 |
aumentar.disabled = true;
|
| 15 |
stepper.classList.add(correta ? 'acerto' : 'erro');
|
| 16 |
|
| 17 |
feedback.className = 'questao-feedback ' + (correta ? 'acerto' : 'erro');
|
| 18 |
feedback.textContent = correta ? 'Correto!' : 'Não foi desta vez.';
|
| 19 |
feedback.hidden = false;
|
| 20 |
|
| 21 |
verificar.hidden = true;
|
| 22 |
reset.hidden = false;
|
| 23 |
});
|
Reiniciar
Limpa o valor, o resultado, e devolve o controle destravado.
| 1 |
reset.addEventListener('click', function () {
|
| 2 |
input.disabled = false;
|
| 3 |
input.value = '';
|
| 4 |
diminuir.disabled = false;
|
| 5 |
aumentar.disabled = false;
|
| 6 |
stepper.classList.remove('acerto', 'erro');
|
| 7 |
|
| 8 |
feedback.hidden = true;
|
| 9 |
reset.hidden = true;
|
| 10 |
verificar.hidden = false;
|
| 11 |
});
|