| lang="fr"> |
Jeux de vocabulaire CE |
| rel="preconnect" href="https://fonts.googleapis.com"> |
| href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;700;800&family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet"> |
:root{ |
--paper:#FBF6EC; |
--rule:#C7DCEC; |
--margin:#E38C8C; |
--ink:#2B3550; |
--accent:#D9534F; |
--accent-dark:#B8433F; |
--success:#3F8F63; |
--success-bg:#E3F3E9; |
--gold:#E0A23B; |
--board:#25392F; |
--board-line:#3E5A4D; |
--chalk:#F4F1E6; |
} |
*{box-sizing:border-box;} |
body{ |
margin:0; |
font-family:'Nunito',sans-serif; |
color:var(--ink); |
background: |
repeating-linear-gradient(var(--paper) 0px, var(--paper) 31px, var(--rule) 32px), |
var(--paper); |
background-position: 0 46px; |
min-height:100vh; |
padding:0 0 40px 0; |
} |
.margin-line{ |
position:fixed; top:0; bottom:0; left:56px; width:2px; background:var(--margin); opacity:.55; z-index:0; |
} |
.wrap{ max-width:780px; margin:0 auto; padding:28px 28px 10px 76px; position:relative; z-index:1;} |
header{ text-align:left; margin-bottom:6px;} |
.stamp{ |
display:inline-block; font-family:'Baloo 2',sans-serif; font-weight:800; font-size:30px; |
color:var(--ink); letter-spacing:.5px; transform:rotate(-1.5deg); |
border-bottom:4px solid var(--gold); padding-bottom:4px; |
} |
.sub{ font-size:15px; color:#5c6580; margin-top:6px; font-weight:600;} |
.tabs{ display:flex; gap:10px; margin:22px 0 18px 0; flex-wrap:wrap;} |
.tab{ |
font-family:'Baloo 2',sans-serif; font-weight:700; font-size:16px; cursor:pointer; |
padding:9px 20px; border-radius:14px 14px 0 0; border:3px solid var(--ink); border-bottom:none; |
background:#fff; color:var(--ink); transform:translateY(4px); transition:transform .15s; |
} |
.tab.active{ background:var(--ink); color:var(--paper); transform:translateY(0);} |
.card{ |
background:#fff; border:3px solid var(--ink); border-radius:4px 18px 4px 18px; |
padding:22px; box-shadow:6px 6px 0 rgba(43,53,80,0.12); |
} |
.cat-row{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:18px;} |
.cat-btn{ |
font-family:'Nunito',sans-serif; font-weight:700; font-size:13px; padding:6px 12px; |
border-radius:20px; border:2px solid var(--ink); background:#fff; cursor:pointer; color:var(--ink); |
} |
.cat-btn.sel{ background:var(--gold); border-color:var(--gold); color:#fff;} |
.score{ font-family:'Baloo 2'; font-weight:700; font-size:14px; color:#5c6580; margin-bottom:10px;} |
.score b{ color:var(--success);} |
/* --- DICTEE --- */ |
.dictee-box{ text-align:center; padding:20px 10px;} |
.say-btn{ |
width:88px; height:88px; border-radius:50%; border:none; background:var(--accent); color:#fff; |
font-size:34px; cursor:pointer; box-shadow:0 4px 0 var(--accent-dark); transition:transform .1s; |
} |
.say-btn:active{ transform:translateY(3px); box-shadow:0 1px 0 var(--accent-dark);} |
.hint{ font-size:13px; color:#8891a8; margin-top:10px; font-weight:600;} |
.accents-row{ display:flex; gap:6px; justify-content:center; flex-wrap:wrap; margin:16px 0 10px 0;} |
.accents-row button{ |
font-family:'Nunito'; font-weight:700; border:2px solid var(--rule); background:#fff; border-radius:8px; |
padding:4px 10px; cursor:pointer; color:var(--ink); font-size:15px; |
} |
.answer-input{ |
width:100%; max-width:360px; font-family:'Baloo 2'; font-size:22px; text-align:center; |
padding:12px; border:3px solid var(--ink); border-radius:12px; margin-top:8px; color:var(--ink); |
} |
.answer-input.correct{ border-color:var(--success); background:var(--success-bg);} |
.answer-input.wrong{ border-color:var(--accent); background:#FBEAEA;} |
.actions{ display:flex; gap:10px; justify-content:center; margin-top:16px; flex-wrap:wrap;} |
.btn{ |
font-family:'Baloo 2'; font-weight:700; font-size:15px; padding:10px 20px; border-radius:12px; |
border:3px solid var(--ink); background:#fff; cursor:pointer; color:var(--ink); |
} |
.btn.primary{ background:var(--ink); color:var(--paper);} |
.feedback{ font-family:'Baloo 2'; font-weight:700; font-size:17px; margin-top:14px; min-height:26px;} |
.feedback.ok{ color:var(--success);} |
.feedback.no{ color:var(--accent-dark);} |
/* --- PENDU --- */ |
.board{ |
background:var(--board); border-radius:14px; padding:20px; text-align:center; |
} |
.board svg{ width:180px; height:170px;} |
.board svg *{ stroke:var(--chalk); } |
.word-blanks{ |
font-family:'Baloo 2'; font-weight:700; font-size:28px; letter-spacing:6px; color:var(--chalk); |
margin:14px 0 6px 0; word-break:break-word; |
} |
.lives{ color:var(--chalk); font-family:'Nunito'; font-weight:700; font-size:13px; opacity:.8;} |
.keyboard{ display:flex; flex-wrap:wrap; gap:5px; justify-content:center; margin-top:16px; max-width:520px; margin-left:auto; margin-right:auto;} |
.key{ |
width:32px; height:38px; border-radius:8px; border:2px solid var(--ink); background:#fff; |
font-family:'Baloo 2'; font-weight:700; font-size:15px; cursor:pointer; color:var(--ink); |
} |
.key:disabled{ opacity:.25; cursor:default;} |
.key.good:disabled{ background:var(--success-bg); border-color:var(--success); opacity:1;} |
.key.bad:disabled{ background:#FBEAEA; border-color:var(--accent); opacity:1;} |
.pendu-msg{ font-family:'Baloo 2'; font-weight:800; font-size:20px; margin-top:12px; min-height:28px;} |
.pendu-msg.ok{ color:var(--success);} |
.pendu-msg.no{ color:var(--accent-dark);} |
footer{ text-align:center; font-size:12px; color:#a3aac0; margin-top:26px; font-weight:600;} |
@media (max-width:480px){ |
.wrap{ padding:22px 14px 10px 46px;} |
.margin-line{ left:26px;} |
.stamp{ font-size:24px;} |
.board svg{ width:140px; height:130px;} |
} |
class="margin-line"> |
class="wrap"> |
|
class="stamp"> 📒 Jeux de vocabulaire CE |
class="sub"> 318 mots à réviser — écoute et écris, ou joue au pendu |
|
class="tabs"> |
class="tab active" data-tab="dictee"> 🎙️ Dictée |
class="tab" data-tab="pendu"> 🖍️ Pendu |
|
class="card"> |
class="cat-row" id="catRow"> |
id="panel-dictee"> |
class="score"> Score : id="dScore">0 / id="dTotal">0 |
class="dictee-box"> |
🔊 |
class="hint"> Clique pour écouter le mot, puis écris-le ci-dessous |
class="accents-row"> |
é è ê |
à â ù |
û ç î |
ï ô œ |
|
type="text" id="answerInput" class="answer-input" placeholder="écris le mot ici" autocomplete="off" spellcheck="false"> |
class="feedback" id="dFeedback"> |
class="actions"> |
Valider |
Mot suivant → |
|
|
|
id="panel-pendu" style="display:none;"> |
class="score"> Score : id="pScore">0 mots trouvés |
class="board"> |
0 0 120 120" fill="none" stroke-width="4" stroke-linecap="round"> |
|
|
|
|
|
|
|
|
|
|
|
class="word-blanks" id="wordBlanks"> _ _ _ _ |
class="lives" id="livesText"> 6 erreurs autorisées |
class="pendu-msg" id="pMsg"> |
|
class="keyboard" id="keyboard"> |
class="actions"> |
Nouveau mot → |
|
|
|
Fait avec les 318 mots de la liste CE • bonne révision ! 🍀 |
const CATEGORIES = { |
"Tous les mots": null, |
"Animaux": ["abeille","boeuf","chameau","chèvre","escargot","fourmi","griffe","ours","pigeon","poil","rat","renard","souris","tigre","tortue","veau"], |
"Nourriture": ["banane","beurre","blé","boisson","bonbon","carotte","déjeuner","dessert","dîner","fraise","goûter","huile","jambon","légume","menu","pâte","plat","poire","raisin","viande","vin"], |
"Corps": ["cœur","doigt","front","genou","langue","larme","menton","œil","ventre","visage","voix","yeux"], |
"Maison et objets": ["bain","bijou","bille","bouteille","bulle","cabane","carte","carton","chaise","chiffon","clé","corde","couteau","escalier","fauteuil","image","mètre","panier","parapluie","piano","plume","roue","salle","toilette","toit","valise","verre","vitrine"], |
"Vêtements": ["chaussure","laine","tablier","vêtement"], |
"Nature": ["bouquet","campagne","champ","chemin","colline","fleuve","forêt","graine","île","nuage","rivière","source","vague","vigne"], |
"Lieux": ["centre","cirque","église","gare","moulin","parc","pont","port","tour"], |
"Mois": ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"], |
"Saisons": ["automne","été","hiver","printemps","saison"], |
"Métiers et gens": ["bonhomme","boucher","boulanger","camarade","cousin","facteur","infirmier","instituteur","maire","marchand","métier"], |
"École": ["addition","apprendre","cartable","crayon","découper","écouter","lecture","lire","page","rentrée","répondre","savoir"], |
"Verbes": ["ajouter","arrêter","arriver","cacher","commencer","comprendre","conduire","continuer","courir","décorer","dormir","emporter","entendre","fabriquer","fermer","finir","fumer","gagner","garder","glisser","habiter","inviter","manquer","mélanger","mesurer","mettre","monter","montrer","nager","oublier","parler","poser","préférer","préparer","prêter","promener","punir","réparer","rire","rouler","sauver","sentir","skier","sortir","souffler","souhaiter","terminer","toucher","trouver","vendre","verser","voler","vouloir"], |
"Adjectifs": ["agréable","amusant","ancien","cher","court","creux","dangereux","debout","doux","drôle","dur","égal","énorme","étroit","facile","formidable","fou","frais","gai","gourmand","haut","inutile","large","lent","magnifique","maigre","mauvais","nouveau","pointu","poli","prêt","rapide","sec","simple","utile","vilain","violet","vivant"], |
"Émotions": ["colère","heureux","malheureux","surprise"], |
"Le temps qui passe": ["autrefois","bientôt","début","lendemain","longtemps","matinée","minute","temps"] |
}; |
const ALL_WORDS = Array.from(new Set(Object.values(CATEGORIES).filter(Boolean).flat())); |
CATEGORIES["Tous les mots"] = ALL_WORDS; |
let currentCategory = "Tous les mots"; |
let currentTab = "dictee"; |
// ---------- Category buttons ---------- |
const catRow = document.getElementById('catRow'); |
Object.keys(CATEGORIES).forEach(name=>{ |
const b = document.createElement('button'); |
b.className = 'cat-btn' + (name===currentCategory ? ' sel' : ''); |
b.textContent = name; |
b.dataset.cat = name; |
b.onclick = ()=>{ |
currentCategory = name; |
document.querySelectorAll('.cat-btn').forEach(x=>x.classList.remove('sel')); |
b.classList.add('sel'); |
if(currentTab==='dictee') newDicteeWord(); else newPenduWord(); |
}; |
catRow.appendChild(b); |
}); |
// ---------- Tabs ---------- |
document.querySelectorAll('.tab').forEach(t=>{ |
t.onclick = ()=>{ |
document.querySelectorAll('.tab').forEach(x=>x.classList.remove('active')); |
t.classList.add('active'); |
currentTab = t.dataset.tab; |
document.getElementById('panel-dictee').style.display = currentTab==='dictee' ? 'block':'none'; |
document.getElementById('panel-pendu').style.display = currentTab==='pendu' ? 'block':'none'; |
if(currentTab==='dictee') newDicteeWord(); else newPenduWord(); |
}; |
}); |
function pool(){ return CATEGORIES[currentCategory]; } |
function randomWord(){ const p = pool(); return p[Math.floor(Math.random()*p.length)]; } |
// ================= DICTEE ================= |
let dWord = ""; |
let dScore = 0, dTotal = 0; |
const answerInput = document.getElementById('answerInput'); |
const dFeedback = document.getElementById('dFeedback'); |
function speak(text){ |
if(!('speechSynthesis' in window)) return; |
const u = new SpeechSynthesisUtterance(text); |
u.lang = 'fr-FR'; u.rate = 0.85; |
window.speechSynthesis.cancel(); |
window.speechSynthesis.speak(u); |
} |
function newDicteeWord(){ |
dWord = randomWord(); |
answerInput.value = ""; |
answerInput.className = "answer-input"; |
dFeedback.textContent = ""; |
dFeedback.className = "feedback"; |
document.getElementById('dTotal').textContent = dTotal; |
setTimeout(()=>speak(dWord), 200); |
} |
document.getElementById('sayBtn').onclick = ()=> speak(dWord); |
document.getElementById('nextDicteeBtn').onclick = newDicteeWord; |
document.querySelectorAll('.accents-row button').forEach(b=>{ |
b.onclick = ()=>{ |
const start = answerInput.selectionStart ?? answerInput.value.length; |
const end = answerInput.selectionEnd ?? answerInput.value.length; |
answerInput.value = answerInput.value.slice(0,start) + b.dataset.c + answerInput.value.slice(end); |
answerInput.focus(); |
answerInput.selectionStart = answerInput.selectionEnd = start + 1; |
}; |
}); |
function checkDictee(){ |
const given = answerInput.value.trim().toLowerCase(); |
const correct = dWord.trim().toLowerCase(); |
dTotal++; |
if(given === correct){ |
dScore++; |
answerInput.className = "answer-input correct"; |
dFeedback.textContent = "Bravo, c'est ça ! ✅"; |
dFeedback.className = "feedback ok"; |
} else { |
answerInput.className = "answer-input wrong"; |
dFeedback.textContent = "Pas tout à fait — la bonne orthographe : " + dWord; |
dFeedback.className = "feedback no"; |
} |
document.getElementById('dScore').textContent = dScore; |
document.getElementById('dTotal').textContent = dTotal; |
} |
document.getElementById('checkBtn').onclick = checkDictee; |
answerInput.addEventListener('keydown', e=>{ if(e.key==='Enter'){ e.preventDefault(); checkDictee(); }}); |
// ================= PENDU ================= |
const AZERTY = "AZERTYUIOPQSDFGHJKLMWXCVBN".split(""); |
let pWord = "", pGuessed = new Set(), pErrors = 0, pScore = 0; |
const MAX_ERR = 6; |
const parts = ["p-head","p-body","p-arm1","p-arm2","p-leg1","p-leg2"]; |
function normLetters(word){ |
return word.split("").filter(ch => /[a-zàâäéèêëîïôöùûüçœ]/i.test(ch)); |
} |
function renderKeyboard(){ |
const kb = document.getElementById('keyboard'); |
kb.innerHTML = ""; |
AZERTY.forEach(letter=>{ |
const btn = document.createElement('button'); |
btn.className = 'key'; |
btn.textContent = letter; |
btn.onclick = ()=> guessLetter(letter.toLowerCase()); |
kb.appendChild(btn); |
}); |
} |
function newPenduWord(){ |
pWord = randomWord(); |
pGuessed = new Set(); |
pErrors = 0; |
document.getElementById('pMsg').textContent = ""; |
document.getElementById('pMsg').className = "pendu-msg"; |
document.getElementById('livesText').textContent = MAX_ERR + " erreurs autorisées"; |
parts.forEach(id=>document.getElementById(id).setAttribute('visibility','hidden')); |
renderKeyboard(); |
updateBlanks(); |
} |
function updateBlanks(){ |
const display = pWord.split("").map(ch=>{ |
if(/[a-zàâäéèêëîïôöùûüçœ]/i.test(ch)){ |
return pGuessed.has(ch.toLowerCase()) ? ch : "_"; |
} |
return ch === " " ? " " : ch; |
}).join(" "); |
document.getElementById('wordBlanks').textContent = display; |
} |
function guessLetter(letter){ |
if(pGuessed.has(letter)) return; |
pGuessed.add(letter); |
const btns = document.querySelectorAll('.key'); |
const btn = Array.from(btns).find(b=>b.textContent.toLowerCase()===letter); |
const isIn = pWord.toLowerCase().includes(letter); |
if(btn){ btn.disabled = true; btn.classList.add(isIn ? 'good':'bad'); } |
if(!isIn){ |
if(pErrors < parts.length) document.getElementById(parts[pErrors]).setAttribute('visibility','visible'); |
pErrors++; |
document.getElementById('livesText').textContent = Math.max(MAX_ERR-pErrors,0) + " erreurs autorisées"; |
} |
updateBlanks(); |
const needed = normLetters(pWord).map(c=>c.toLowerCase()); |
const won = needed.every(l=>pGuessed.has(l)); |
if(won){ |
pScore++; |
document.getElementById('pScore').textContent = pScore; |
document.getElementById('pMsg').textContent = "Gagné ! Le mot était bien « " + pWord + " » 🎉"; |
document.getElementById('pMsg').className = "pendu-msg ok"; |
document.querySelectorAll('.key').forEach(b=>b.disabled=true); |
} else if(pErrors >= MAX_ERR){ |
document.getElementById('pMsg').textContent = "Dommage... le mot était « " + pWord + " »"; |
document.getElementById('pMsg').className = "pendu-msg no"; |
document.querySelectorAll('.key').forEach(b=>b.disabled=true); |
} |
} |
document.getElementById('nextPenduBtn').onclick = newPenduWord; |
// init |
newDicteeWord(); |
newPenduWord(); |