. Word Unscramble Game JavaScript – Free HTML CSS | Coodeverse Skip to main content

Word Builder – Free Vanilla JavaScript Unscramble Word Puzzle Game

Word Builder is a free, copy-paste ready word unscramble puzzle game built with pure HTML, CSS, and vanilla JavaScript — no frameworks, no dependencies. Players click glassmorphism letter tiles (built with backdrop-filter: blur(8px) and rgba transparency) to select letters in any order and form the correct word based on a text hint. Each tile highlights yellow (#ffeb3b) when selected with a transform: scale(1.15) pop effect. The current selection is displayed in real time above the buttons. Three action buttons let players Check Word for instant green/red feedback, Shuffle Letters to reshuffle the tiles using the Fisher-Yates algorithm, and New Word for a fresh random challenge from the 12-word educational pool.

The 12-word pool includes hints ideal for children and vocabulary learners: ELEPHANT ("Largest land animal"), GIRAFFE ("Has the longest neck"), BUTTERFLY ("Comes from a caterpillar"), RAINBOW ("Appears after rain"), PIZZA ("Italian food with cheese"), COMPUTER ("You are using one now"), OCEAN, MUSIC, HAPPY, GALAXY, DRAGON, and SUNSHINE. The game demonstrates key JavaScript concepts: Array.prototype.forEach for DOM rendering, closure-captured index values for letter identity tracking, .find() and .filter() for selection state management, and array sort by index for ordered answer assembly.

What's Included in the Download

How Letter Selection and Answer Assembly Works

Each letter <div> is rendered by renderLetters() using scrambled.forEach((letter, idx) => {...}). The idx value is captured in the click handler closure. Clicking calls toggleLetter(letter, div, idx): if selected.find(s => s.idx === idx) returns a match, the letter is deselected; otherwise {letter, idx} is pushed to the selected array and .selected class is added. showCurrentAnswer() sorts selected by idx ascending and joins the letters — this displays them in scrambled-position order, not click order. The submit handler compares this sorted string against currentWord.

How to Add Words and Customize for the Classroom

Edit the words array — each object has word (uppercase string) and hint (description). Replace all 12 entries with subject vocabulary: science terms (PHOTOSYNTHESIS, MITOCHONDRIA), geography (MEDITERRANEAN, CONTINENT), coding terms (FUNCTION, VARIABLE), or any spelling list. The game handles any word length automatically. To add a score counter, declare a let score = 0 variable, increment on correct answers, and display in a UI element. Add a word count progress bar to show how many words remain.

Best Use Cases

Word Builder is ideal for: classroom vocabulary exercises, spelling bee practice apps, kids learning JavaScript, ESL and English learning tools, educational JavaScript tutorials, frontend bootcamp portfolio projects, subject-specific word games, and as a foundation for adding difficulty levels, timers, hint reveals, streak counters, or multiplayer score boards.

License

Released under Creative Commons Attribution 4.0 International (CC BY 4.0). Free for personal, educational, and commercial use with attribution to Coodeverse.

Source Code

<!DOCTYPE html>
<html lang="en">
<head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Word Builder</title> <style> body { margin: 0; font-family: 'Segoe UI', Arial, sans-serif; background: linear-gradient(135deg, #667eea, #764ba2); color: white; min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 20px 10px; box-sizing: border-box; } h1 { font-size: 2.8em; margin: 10px 0; text-shadow: 2px 2px 10px rgba(0,0,0,0.4); } .hint { font-size: 1.3em; margin-bottom: 20px; opacity: 0.9; } #scrambled { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin: 30px 0; max-width: 90%; } .letter { width: 68px; height: 68px; background: rgba(255,255,255,0.25); border-radius: 16px; line-height: 68px; font-size: 2em; font-weight: bold; text-align: center; cursor: pointer; user-select: none; transition: all 0.3s; backdrop-filter: blur(8px); border: 3px solid rgba(255,255,255,0.4); flex-shrink: 0; } .letter:hover { background: rgba(255,255,255,0.45); transform: translateY(-6px) scale(1.08); } .letter.selected { background: #ffeb3b; color: #333; transform: scale(1.15); border-color: #333; } #answer { margin: 40px 0; font-size: 3em; font-weight: bold; min-height: 80px; letter-spacing: 6px; } .buttons { margin: 20px 0; } button { padding: 14px 28px; margin: 8px; font-size: 1.1em; background: rgba(255,255,255,0.25); color: white; border: none; border-radius: 50px; cursor: pointer; transition: 0.3s; backdrop-filter: blur(8px); } button:hover { background: #ffeb3b; color: #333; transform: translateY(-4px); } #message { margin-top: 20px; font-size: 1.6em; font-weight: bold; min-height: 50px; } .correct { color: #4caf50; } .wrong { color: #f44336; } @media (max-width: 480px) { .letter { width: 58px; height: 58px; line-height: 58px; font-size: 1.8em; } h1 { font-size: 2.2em; } #answer { font-size: 2.4em; } } </style>
</head>
<body> <h1>Word Builder</h1> <div class="hint">Hint: <span id="hint"></span></div> <div id="scrambled"></div> <div id="answer">?</div> <div class="buttons"> <button id="submit">Check Word</button> <button id="newWord">New Word</button> <button id="shuffle">Shuffle Letters</button> </div> <div id="message"></div> <script> const words = [ { word: "ELEPHANT", hint: "Largest land animal" }, { word: "GIRAFFE", hint: "Has the longest neck" }, { word: "BUTTERFLY", hint: "Comes from a caterpillar" }, { word: "RAINBOW", hint: "Appears after rain" }, { word: "PIZZA", hint: "Italian food with cheese" }, { word: "COMPUTER", hint: "You are using one now" }, { word: "OCEAN", hint: "Covers 71% of Earth" }, { word: "MUSIC", hint: "Universal language" }, { word: "HAPPY", hint: "A positive feeling" }, { word: "GALAXY", hint: "The Milky Way is one" }, { word: "DRAGON", hint: "Mythical fire-breathing creature" }, { word: "SUNSHINE", hint: "Bright and warm from the sky" } ]; let currentWord = ""; let scrambled = []; let selected = []; const scrambledDiv = document.getElementById("scrambled"); const answerDiv = document.getElementById("answer"); const hintSpan = document.getElementById("hint"); const messageDiv = document.getElementById("message"); function newGame() { const i = Math.floor(Math.random() * words.length); currentWord = words[i].word; hintSpan.textContent = words[i].hint; scrambled = currentWord.split(""); shuffleArray(scrambled); selected = []; messageDiv.textContent = ""; answerDiv.textContent = "?"; renderLetters(); } function renderLetters() { scrambledDiv.innerHTML = ""; scrambled.forEach((letter, idx) => { const div = document.createElement("div"); div.className = "letter"; div.textContent = letter; div.onclick = () => toggleLetter(letter, div, idx); scrambledDiv.appendChild(div); }); } function toggleLetter(letter, el, idx) { const alreadySelected = selected.find(s => s.idx === idx); if (alreadySelected) { selected = selected.filter(s => s.idx !== idx); el.classList.remove("selected"); } else { selected.push({ letter, idx }); el.classList.add("selected"); } showCurrentAnswer(); } function showCurrentAnswer() { if (selected.length === 0) { answerDiv.textContent = "?"; return; } const sorted = selected.slice().sort((a,b) => a.idx - b.idx); answerDiv.textContent = sorted.map(x => x.letter).join(""); } function shuffleArray(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } } document.getElementById("shuffle").onclick = () => { shuffleArray(scrambled); renderLetters(); selected.forEach(s => { const newIndex = scrambled.indexOf(s.letter); if (newIndex !== -1) s.idx = newIndex; }); showCurrentAnswer(); }; document.getElementById("submit").onclick = () => { const guess = selected.slice().sort((a,b) => a.idx - b.idx).map(x => x.letter).join(""); if (guess === currentWord) { messageDiv.textContent = "Correct! Excellent!"; messageDiv.className = "correct"; } else { messageDiv.textContent = "Not yet… keep trying!"; messageDiv.className = "wrong"; } }; document.getElementById("newWord").onclick = newGame; // Start newGame(); </script>
</body>
</html>

Frequently Asked Questions

Common questions about the free Word Builder vanilla JavaScript unscramble word puzzle.

Yes — 100% free under Creative Commons Attribution 4.0. No sign-up, no payment. Click Download Project and use it in personal, educational, or commercial projects with attribution to Coodeverse.

You need: (1) a word array with hints; (2) a Fisher-Yates shuffle to randomize letters; (3) rendered letter divs with click handlers; (4) a selected array tracking {letter, idx} pairs; (5) an answer display sorting selected by idx and joining; (6) a submit handler comparing the assembled string to the target word. In Word Builder, clicking adds/removes entries from selected and toggles the .selected CSS class (yellow highlight).

The Fisher-Yates (Knuth) shuffle iterates from the last element down to index 1, picks a random index j from 0 to i, and swaps: [arr[i], arr[j]] = [arr[j], arr[i]]. This produces a uniformly random permutation in O(n) time. Word Builder uses it at game start to scramble the letters and again when Shuffle Letters is clicked.

Each tile uses background: rgba(255,255,255,0.25) for transparency, backdrop-filter: blur(8px) for the frosted glass blur, and border: 3px solid rgba(255,255,255,0.4) for the glass edge. On hover, background increases to rgba(255,255,255,0.45) and transform: translateY(-6px) scale(1.08) lifts it. When selected, background: #ffeb3b and transform: scale(1.15) pop it forward with yellow highlight.

Each letter's idx is captured via forEach closure. Clicking calls toggleLetter(letter, div, idx). If selected.find(s => s.idx === idx) matches, the letter is deselected; otherwise {letter, idx} is pushed to selected. showCurrentAnswer() sorts selected by idx ascending and joins — showing letters in scrambled-position order, not click order.

Edit the words array — each object has word (uppercase) and hint. Replace all 12 entries with your vocabulary: science terms, geography, history, coding terms, or ESL words. The game handles any word length. Add a score counter (let score = 0, increment on correct) and display it in a UI element. Add a countdown timer with setInterval for challenge mode.

Browse the full collection at coodeverse.com/projects — Word Typing Adventure (type-to-move runner), VORTEX Interactive Canvas, Particle Fireworks, Holographic Login and more. All 100% free with complete source code.