Todas as atividades
Jogo e Combinação

Palavras Cruzadas

Grade com palavras ocultas que o aprendiz descobre a partir de dicas. Reforça vocabulário técnico de forma lúdica, combinando raciocínio e memorização.

Conhecimento cruzadas palavras vocabulário crossword

Experimente

Vocabulário de Design Instrucional

1,2
3

1. HORIZONTAL

Modelo clássico de DI: Análise, Design, Desenvolvimento, Implementação, Avaliação

2. VERTICAL

Modelo de motivação de Keller: Atenção, Relevância, Confiança, Satisfação

3. HORIZONTAL

Sistema de gerenciamento de aprendizagem (sigla em inglês)

Código-fonte

PHP

Dados de exemplo

Cada palavra tem posição (linha/coluna), direção e uma dica. Palavras que se cruzam precisam compartilhar a mesma letra na célula onde se tocam — ADDIE e ARCS dividem o "A", ARCS e LMS dividem o "S".

1 <?php
2 $palavras = [
3 ['palavra' => 'ADDIE', 'dica' => 'Modelo clássico de design instrucional: Análise, Design, Desenvolvimento, Implementação, Avaliação', 'direcao' => 'horizontal', 'linha' => 0, 'coluna' => 2],
4 ['palavra' => 'ARCS', 'dica' => 'Modelo de motivação de Keller: Atenção, Relevância, Confiança, Satisfação', 'direcao' => 'vertical', 'linha' => 0, 'coluna' => 2],
5 ['palavra' => 'LMS', 'dica' => 'Sistema de gerenciamento de aprendizagem (sigla em inglês)', 'direcao' => 'horizontal', 'linha' => 3, 'coluna' => 0],
6 ];

Montar a grade

Calcula em qual célula cada letra cai e guarda o retângulo (linMin..linMax, colMin..colMax) realmente ocupado — desenhar só essa região, em vez de uma grade fixa inteira, evita sobra vazia empurrando o quebra-cabeça pro canto.

1 $linhas = 5;
2 $colunas = 8;
3 $grade = array_fill(0, $linhas, array_fill(0, $colunas, null));
4 $linMin = $linhas; $linMax = -1; $colMin = $colunas; $colMax = -1;
5
6 foreach ($palavras as $i => $p) {
7 $palavra = strtoupper($p['palavra']);
8 $lin = $p['linha'];
9 $col = $p['coluna'];
10 $dir = $p['direcao'];
11 for ($k = 0; $k < strlen($palavra); $k++) {
12 $l = $dir === 'horizontal' ? $lin : $lin + $k;
13 $c = $dir === 'horizontal' ? $col + $k : $col;
14 if ($l < $linhas && $c < $colunas) {
15 // Duas palavras podem começar na mesma célula (uma horizontal e
16 // uma vertical cruzando na primeira letra de ambas) — por isso
17 // os números se acumulam num array em vez de sobrescrever.
18 $numeros = $grade[$l][$c]['numeros'] ?? [];
19 if ($k === 0) $numeros[] = $i + 1;
20 $grade[$l][$c] = ['letra' => $palavra[$k], 'numeros' => $numeros];
21 $linMin = min($linMin, $l); $linMax = max($linMax, $l);
22 $colMin = min($colMin, $c); $colMax = max($colMax, $c);
23 }
24 }
25 }
26 $colunasVisiveis = $colMax - $colMin + 1;
27 ?>

Grade

Célula com letra vira um input de uma posição só; célula sem letra é o quadrado bloqueado, sempre escuro (convenção visual de palavras cruzadas, não muda com o tema).

1 <div class="questao" data-tipo="palavras-cruzadas">
2
3 <div class="grade" style="grid-template-columns: repeat(<?= $colunasVisiveis ?>, 48px);">
4 <?php for ($r = $linMin; $r <= $linMax; $r++): for ($c = $colMin; $c <= $colMax; $c++): $cell = $grade[$r][$c]; ?>
5 <?php if ($cell): ?>
6 <div class="celula-casca">
7 <?php if (!empty($cell['numeros'])): ?><span class="numero"><?= implode(',', $cell['numeros']) ?></span><?php endif; ?>
8 <input type="text" maxlength="1" class="celula" data-letra="<?= $cell['letra'] ?>">
9 </div>
10 <?php else: ?>
11 <div class="bloqueado"></div>
12 <?php endif; ?>
13 <?php endfor; endfor; ?>
14 </div>

Pistas

Uma pista por palavra, numerada; a resposta nasce oculta e só some com o "hidden" depois de verificar.

1 <div class="pistas">
2 <?php foreach ($palavras as $i => $p): ?>
3 <div class="pista">
4 <p class="pista-numero"><?= $i + 1 ?>. <?= strtoupper($p['direcao']) ?></p>
5 <p class="pista-texto"><?= htmlspecialchars($p['dica']) ?></p>
6 <p class="resposta hidden">Resposta: <?= htmlspecialchars(strtoupper($p['palavra'])) ?></p>
7 </div>
8 <?php endforeach; ?>
9 </div>

Ações

Verificar, painel de resultado e reiniciar — os dois últimos nascem ocultos.

1 <button type="button" class="questao-verificar">Verificar resposta</button>
2
3 <div class="questao-painel" hidden>
4 <p class="questao-painel-mensagem"></p>
5 </div>
6
7 <button type="button" class="questao-reset" hidden>Tentar novamente</button>
8
9 </div>
CSS

Grade

Colunas dinâmicas via style inline — o número de colunas depende do que a atividade realmente ocupa.

1 .grade {
2 display: grid;
3 gap: 4px;
4 margin-bottom: 20px;
5 justify-content: center;
6 }

Célula de resposta

Casca quadrada com o input de uma letra centralizado dentro.

1 .celula-casca {
2 position: relative;
3 width: 48px;
4 height: 48px;
5 background: #f1f5f9;
6 border: 1px solid #cbd5e1;
7 border-radius: 4px;
8 display: flex;
9 align-items: center;
10 justify-content: center;
11 }
12
13 .celula {
14 width: 36px;
15 height: 36px;
16 background: transparent;
17 border: none;
18 text-align: center;
19 text-transform: uppercase;
20 font-size: 18px;
21 font-weight: 700;
22 color: #1e293b;
23 outline: none;
24 }
25
26 .celula:focus {
27 color: #4f46e5;
28 }

Número da pista

Pequeno rótulo no canto da célula onde uma ou mais palavras começam.

1 .numero {
2 position: absolute;
3 top: 2px;
4 left: 4px;
5 font-size: 10px;
6 font-weight: 700;
7 color: #4f46e5;
8 line-height: 1;
9 }

Quadrado bloqueado

Sempre escuro, nos dois temas — é a convenção visual de palavras cruzadas (quadrado sem letra é bloqueado), não a cor de fundo do card.

1 .bloqueado {
2 width: 48px;
3 height: 48px;
4 background: #1e293b;
5 }

Pistas

Uma caixa por palavra, com número, dica e a resposta (oculta até verificar).

1 .pistas {
2 display: flex;
3 flex-direction: column;
4 gap: 12px;
5 margin-bottom: 20px;
6 }
7
8 .pista {
9 padding: 12px;
10 border: 1px solid #cbd5e1;
11 border-radius: 10px;
12 background: #f8fafc;
13 }
14
15 .pista-numero {
16 margin: 0 0 4px;
17 font-size: 12px;
18 font-weight: 700;
19 color: #4f46e5;
20 }
21
22 .pista-texto {
23 margin: 0;
24 font-size: 14px;
25 color: #475569;
26 }

Resposta da pista

Some por padrão (classe hidden); o JS remove essa classe ao verificar.

1 .resposta {
2 margin: 8px 0 0;
3 font-size: 14px;
4 font-weight: 600;
5 color: #059669;
6 }
7
8 .hidden {
9 display: none;
10 }

Ações

Botões de largura total, um de cada vez na tela.

1 .questao-verificar,
2 .questao-reset {
3 display: block;
4 width: 100%;
5 padding: 12px 16px;
6 border: none;
7 border-radius: 10px;
8 font: inherit;
9 font-weight: 600;
10 cursor: pointer;
11 }
12
13 .questao-verificar {
14 background: #4f46e5;
15 color: #fff;
16 }
17
18 .questao-reset {
19 background: #e5e7eb;
20 color: #1f2937;
21 }

Estado oculto

O atributo hidden nativo tem a mesma especificidade da regra de exibição acima — sem isto, "Tentar novamente" apareceria antes de verificar.

1 .questao-verificar[hidden],
2 .questao-reset[hidden] {
3 display: none;
4 }

Painel de resultado

Caixa de destaque com a contagem de acertos, abaixo das pistas.

1 .questao-painel {
2 margin: 16px 0;
3 padding: 16px;
4 border-radius: 12px;
5 background: #1e3a8a;
6 color: #dbeafe;
7 font-weight: 600;
8 }
JavaScript

Encontrar os elementos da questão

Localiza as células, as respostas ocultas de cada pista e as ações.

1 document.addEventListener('DOMContentLoaded', function () {
2 document.querySelectorAll('.questao[data-tipo="palavras-cruzadas"]').forEach(function (questao) {
3 var celulas = questao.querySelectorAll('.celula');
4 var respostas = questao.querySelectorAll('.resposta');
5 var verificar = questao.querySelector('.questao-verificar');
6 var painel = questao.querySelector('.questao-painel');
7 var reset = questao.querySelector('.questao-reset');

Verificar

Tentativa única — compara cada célula com a letra esperada, trava a grade inteira e revela a resposta de cada pista separadamente (nunca uma sequência única com todas as palavras juntas).

1 verificar.addEventListener('click', function () {
2 var corretos = 0, total = 0;
3 celulas.forEach(function (c) {
4 total++;
5 var valor = (c.value || '').trim().toUpperCase();
6 var esperado = (c.dataset.letra || '').toUpperCase();
7 if (valor === esperado) corretos++;
8 c.disabled = true;
9 });
10
11 var mensagem = painel.querySelector('.questao-painel-mensagem');
12 mensagem.textContent = corretos === total
13 ? 'Todas as respostas corretas!'
14 : corretos + '/' + total + ' letras corretas.';
15 painel.hidden = false;
16
17 respostas.forEach(function (r) { r.classList.remove('hidden'); });
18
19 verificar.hidden = true;
20 reset.hidden = false;
21 });

Reiniciar

Limpa os valores, reabilita as células e esconde as respostas de novo.

1 reset.addEventListener('click', function () {
2 celulas.forEach(function (c) { c.value = ''; c.disabled = false; });
3 respostas.forEach(function (r) { r.classList.add('hidden'); });
4 painel.hidden = true;
5 verificar.hidden = false;
6 reset.hidden = true;
7 });