Hangman Game using JavaScript, HTML, and CSS

In this tutorial, we will build the Hangman Game step-by-step using JavaScipt, HTML, and CSS.

Objective: The player must guess a hidden word by selecting letters within a limited number of chances.

Project Specifications

Display Hangman Pole and Figure Using SVG: Create the hangman figure and pole using scalable vector graphics (SVG). This approach ensures that your graphics scale nicely across different screen sizes without losing quality.

Generate a Random Word: Implement functionality to randomly select a word from a predefined list. This word will be the target for the player to guess.

Display Word in UI with Correct Letters
: As the player guesses letters correctly, these letters should be revealed in the word's placeholder on the user interface.

Display Wrong Letters: Incorrect guesses should be tracked and displayed to the player, providing feedback and strategy for future guesses.

Show Notification When Selecting a Letter Twice: Implement a notification system to alert the player if they attempt to guess a letter that has already been selected.

Show Popup on Win or Lose: Depending on the outcome, display a popup message congratulating the player for winning or informing them of their loss, revealing the correct word if they failed to guess it.

Play Again Button to Reset Game: Include a button within the popup message that allows players to restart the game, reset the game state, and select a new word.


Create a workspace folder with the name hangman-game and within this folder, create three files:
  • index.html - for the app structure.
  • style.css - for styling the app.
  • script.js - for the app's functionality.

1. index.html - HTML Structure

The HTML provides the skeleton of our game, including the hangman SVG figure, containers for displaying wrong guesses, the mystery word, notification popups, and a play-again button. It sets up the playing field for our interactive game.

Let's open the index.html file and add the following HTML code to it:
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <p>Find the hidden word - Enter a letter</p>
    <div class="game-container">
      <svg height="250" width="200" class="figure-container">
        <!-- Rod -->
        <line x1="60" y1="20" x2="140" y2="20" />
        <line x1="140" y1="20" x2="140" y2="50" />
        <line x1="60" y1="20" x2="60" y2="230" />
        <line x1="20" y1="230" x2="100" y2="230" />

        <!-- Head -->
        <circle cx="140" cy="70" r="20" class="figure-part" />
        <!-- Body -->
        <line x1="140" y1="90" x2="140" y2="150" class="figure-part" />
        <!-- Arms -->
        <line x1="140" y1="120" x2="120" y2="100" class="figure-part" />
        <line x1="140" y1="120" x2="160" y2="100" class="figure-part" />
        <!-- Legs -->
        <line x1="140" y1="150" x2="120" y2="180" class="figure-part" />
        <line x1="140" y1="150" x2="160" y2="180" class="figure-part" />

      <div class="wrong-letters-container">
        <div id="wrong-letters"></div>

      <div class="word" id="word"></div>

    <!-- Container for final message -->
    <div class="popup-container" id="popup-container">
      <div class="popup">
        <h2 id="final-message"></h2>
        <h3 id="final-message-reveal-word"></h3>
        <button id="play-button">Play Again</button>

    <!-- Notification -->
    <div class="notification-container" id="notification-container">
      <p>You have already entered this letter</p>

    <script src="script.js"></script>

2. style.css - CSS Styling 

The CSS styles add life to our game by styling the hangman figure, aligning elements on the page, and designing the popup notifications for an engaging user experience. The use of colors, borders, and transitions enhances the visual feedback for the player's actions.

Let's open the style.css file and add the following content to it:
* {
  box-sizing: border-box;

body {
  background-color: #34495e;
  color: #fff;
  font-family: Arial, Helvetica, sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 80vh;
  margin: 0;
  overflow: hidden;

h1 {
  margin: 20px 0 0;

.game-container {
  padding: 20px 30px;
  position: relative;
  margin: auto;
  height: 350px;
  width: 450px;

.figure-container {
  fill: transparent;
  stroke: #fff;
  stroke-width: 4px;
  stroke-linecap: round;

.figure-part {
  display: none;

.wrong-letters-container {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  text-align: right;

.wrong-letters-container p {
  margin: 0 0 5px;

.wrong-letters-container span {
  font-size: 24px;

.word {
  display: flex;
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);

.letter {
  border-bottom: 3px solid #2980b9;
  display: inline-flex;
  font-size: 30px;
  align-items: center;
  justify-content: center;
  margin: 0 3px;
  height: 50px;
  width: 20px;

.popup-container {
  background-color: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  /* display: flex; */
  display: none;
  align-items: center;
  justify-content: center;

.popup {
  background: #2980b9;
  border-radius: 5px;
  box-shadow: 0 15px 10px 3px rgba(0, 0, 0, 0.1);
  padding: 20px;
  text-align: center;

.popup button {
  cursor: pointer;
  background-color: #fff;
  color: #2980b9;
  border: 0;
  margin-top: 20px;
  padding: 12px 20px;
  font-size: 16px;

.popup button:active {
  transform: scale(0.98);

.popup button:focus {
  outline: 0;

.notification-container {
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 10px 10px 0 0;
  padding: 15px 20px;
  position: absolute;
  bottom: -50px;
  transition: transform 0.3s ease-in-out;

.notification-container p {
  margin: 0;

.notification-container.show {
  transform: translateY(-50px);

3. script.js - JavaScript Logic 

The JavaScript file is the heart of the Hangman game. It controls the game's logic, from generating random words, handling keyboard events for letter guesses, updating the display for correct and wrong letters, and showing notifications and popups based on the game's state. The script dynamically updates the HTML content based on player interactions, providing a smooth and interactive gaming experience.

Open the script.js file and add the following code to it:  
const wordEl = document.getElementById('word');
const wrongLettersEl = document.getElementById('wrong-letters');
const playAgainBtn = document.getElementById('play-button');
const popup = document.getElementById('popup-container');
const notification = document.getElementById('notification-container');
const finalMessage = document.getElementById('final-message');
const finalMessageRevealWord = document.getElementById('final-message-reveal-word');

const figureParts = document.querySelectorAll('.figure-part');

const words = ['application', 'programming', 'interface', 'wizard'];

let selectedWord = words[Math.floor(Math.random() * words.length)];

let playable = true;

const correctLetters = [];
const wrongLetters = [];

// Show hidden word
function displayWord() {
	wordEl.innerHTML = `
				letter => `
          <span class="letter">
            ${correctLetters.includes(letter) ? letter : ''}

	const innerWord = wordEl.innerText.replace(/[ \n]/g, '');

	if (innerWord === selectedWord) {
		finalMessage.innerText = 'Congratulations! You won! 😃';
		finalMessageRevealWord.innerText = '';
		popup.style.display = 'flex';

		playable = false;

// Update the wrong letters
function updateWrongLettersEl() {
	// Display wrong letters
	wrongLettersEl.innerHTML = `
    ${wrongLetters.length > 0 ? '<p>Wrong</p>' : ''}
    ${wrongLetters.map(letter => `<span>${letter}</span>`)}

	// Display parts
	figureParts.forEach((part, index) => {
		const errors = wrongLetters.length;

		if (index < errors) {
			part.style.display = 'block';
		} else {
			part.style.display = 'none';

	// Check if lost
	if (wrongLetters.length === figureParts.length) {
		finalMessage.innerText = 'Unfortunately you lost. 😕';
		finalMessageRevealWord.innerText = `...the word was: ${selectedWord}`;
		popup.style.display = 'flex';

		playable = false;

// Show notification
function showNotification() {

	setTimeout(() => {
	}, 2000);

// Keydown letter press
window.addEventListener('keydown', e => {
	if (playable) {
		if (e.keyCode >= 65 && e.keyCode <= 90) {
			const letter = e.key.toLowerCase();

			if (selectedWord.includes(letter)) {
				if (!correctLetters.includes(letter)) {

				} else {
			} else {
				if (!wrongLetters.includes(letter)) {

				} else {

// Restart game and play again
playAgainBtn.addEventListener('click', () => {
	playable = true;

	//  Empty arrays

	selectedWord = words[Math.floor(Math.random() * words.length)];



	popup.style.display = 'none';


Open index.html in Browser 

Let's open the index.html file in the browser, and you will be able to see the following screen:




Building a Hangman game using JavaScript, HTML, and CSS is a rewarding project that encompasses various aspects of web development. It not only reinforces fundamental programming concepts but also offers a platform for creative expression through game design. 

Following the project specifications and understanding the implementation details, you can create an entertaining web-based Hangman game that challenges and delights players while showcasing your development skills.