< BACK TO COMPONENTS

Learn How to Create a Hangman Game using HTML, CSS, and JavaScript

Faraz

By Faraz -

Discover the process of creating a Hangman Game using HTML, CSS, and JavaScript. Follow our step-by-step guide for beginners.


Learn How to Create a Hangman Game using HTML, CSS, and JavaScript.jpg

Hangman is a classic word-guessing game that has entertained and challenged players for generations. The objective of the game is simple: guess the hidden word by suggesting letters within a limited number of attempts. Each incorrect guess leads to the drawing of a hanging stick figure, representing the "hangman." The player's goal is to guess the word correctly before the hangman is complete.


Building a Hangman Game using HTML, CSS, and JavaScript is an exciting project that combines creativity, logic, and programming skills. Whether you are a beginner in web development or looking to expand your coding knowledge, this step-by-step tutorial will guide you through the process of creating your own interactive Hangman Game from scratch.


By following this tutorial, you will gain a solid understanding of how to structure an HTML page, style it using CSS, and implement the game's functionality using JavaScript. The game mechanics include generating a random word, tracking user guesses, updating the game state, and providing visual feedback to the player.


Not only will you learn the technical aspects of creating a Hangman Game, but you will also have the opportunity to customize and enhance the game to suit your preferences. You can experiment with different themes, difficulty levels, and additional features to make your Hangman Game unique and enjoyable.


Whether you plan to showcase your game development skills, challenge friends to play your creation, or simply have fun building and playing the game yourself, this Hangman Game tutorial will provide you with the necessary knowledge and guidance to get started. So, let's dive into the exciting world of web development and create an engaging Hangman Game using HTML, CSS, and JavaScript!


Join My Telegram Channel to Download the Projects Source Code: Click Here


Prerequisites:

Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.


Code by: Alina-Balteanu

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our hangman game.


After creating the files just paste the following below codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.


Here's an explanation of the code:


1. <!DOCTYPE html>: This line declares the document type as HTML5.


2. <html lang="en" dir="ltr">: This tag represents the root element of the HTML document and specifies the language as English (en) and text direction as left-to-right (ltr).


3. <head>: This section contains meta-information and external resources related to the web page.


  • <meta charset="utf-8">: Specifies the character encoding for the HTML document as UTF-8, which supports a wide range of characters.
  • <title>Hangman Game</title>: Sets the title of the web page displayed in the browser's title bar.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: Defines the viewport properties for responsive web design.
  • <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" type="text/css">: Links an external CSS file called "normalize.min.css" that normalizes CSS styles across different browsers.
  • <link href="https://fonts.googleapis.com/css?family=Permanent+Marker" rel="stylesheet">: Links an external font called "Permanent Marker" from Google Fonts.
  • <link rel="stylesheet" href="styles.css">: Links an external CSS file called "styles.css" specific to this web page.

4. <body>: This section represents the visible content of the web page.


  • <main>: Represents the main content of the page.
  • <div class="outside-wrapper">: A container for grouping related elements with a CSS class called "outside-wrapper".
  • <h1 id="statusMessage">Vanilla JavaScript Hangman Game</h1>: A heading element with the text "Vanilla JavaScript Hangman Game" and an ID "statusMessage" for JavaScript manipulation.
  • SVG (Scalable Vector Graphics): An inline SVG element that defines a hangman illustration using various lines and an image. It's used to visually represent the Hangman game progress.
  • <div class="inside-wrapper">: A container for grouping related elements with a CSS class called "inside-wrapper".
  • <img>: Several images with different IDs and CSS classes representing the remaining lives or guesses in the game.
  • <p id="wrongLetters" class="hidden">Wrong letters:<br> <span></span></p>: A paragraph element with the ID "wrongLetters" and a CSS class "hidden" initially. It displays the wrong letters guessed by the player.
  • <div class="wrapper">: A container for grouping related elements with a CSS class called "wrapper".
  • <p id="categoryName">Category:smtg</p>: A paragraph element with the ID "categoryName" displaying the game category.
  • <div id="guessWrapper">: A container for displaying the current state of the word being guessed.
  • <div class="button-wrapper">: A container for grouping related elements with a CSS class called "button-wrapper".
  • <input type="text" id="userLetter" maxlength="1" size="4" autocomplete="off">: An input field for the user to enter a single letter for guessing.
  • <button type="button" id="guessButton">Guess</button>: A button element with the ID "guessButton" that triggers the guessing action.
  • <div class="wrapper warning">: A container for grouping related elements with a CSS class called "wrapper" and "warning".
  • <span id="warningText" class="hidden"> </span>: A span element with the ID "warningText" and a CSS class "hidden" initially. It displays any warning messages.
  • <button type="button" id="newGame">New Game</button>: A button element with the ID "newGame" to start a new game.
  • <script src="script.js"></script>: Links an external JavaScript file called "script.js" that contains the logic and functionality of the Hangman game.

This is the basic structure of our hangman game using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the hangman game is in place, the next step is to add styling to the hangman game using CSS. CSS allows us to control the visual appearance of the website, including things like layout, color, and typography.


Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our hangman game.


Here's an explanation of the code:


The code starts with setting the height, margin, and padding of the HTML and body elements to 100%, 0, and 0 respectively. This ensures that the HTML and body elements take up the full height of the viewport without any margin or padding.


The body element is styled with a background image using the background property. The image URL is specified, and the background-size is set to contain, meaning the image will be scaled to fit within the container without stretching. The background-repeat property is set to repeat to repeat the image horizontally and vertically if it doesn't cover the entire body element. The font-family property sets the font for the body text, using the "Permanent Marker" font if available. The position property is set to relative to establish a positioning context for absolutely positioned child elements.


The main element is styled as a flex container with a column direction (flex-direction: column). This means its child elements will be stacked vertically.


The .wrapper and .button-wrapper classes are applied to elements that have text centered (text-align: center) and have a margin of 10px.


The .outside-wrapper class is applied to an element with a bottom margin of 20px and text centered. The nth-child(2) selector targets the second element with this class and applies additional styling, setting its width to 100%, top margin to 20px, and making it a flex container with centered content. The max-height property restricts the height of this element to 300px.


The .outside-wrapper:nth-child(3) selector targets the third element with the class .outside-wrapper. It sets a bottom margin of "auto", which pushes the element towards the top, a fixed height of 178px, and a width of 100%.


The .hidden class is used to hide elements by setting display: none.


The #statusMessage ID targets an element with specific styling properties. It has top and bottom margins of 20px, padding of 10px, and box-sizing set to border-box (includes padding and border in the element's total width and height). The text within this element is centered (text-align: center) and has a fixed height of 94px.


The svg selector targets SVG elements and applies a transformation to rotate them by -1 degree.


The .lives class is applied to elements with a fixed width of 40px and auto height (maintains the aspect ratio).


The .hiddenLife class is applied to elements that are initially visible (display: inline-block) and then animated using the lifeAway keyframes animation. The animation scales the element down to 0, rotates it, and gradually reduces the opacity.


The #categoryName ID targets an element and sets the font size to 20px and margin values.


The #warningText ID targets an element and sets the text color to a specific shade of red.


The .warning class is applied to elements with a fixed height of 20px.


The #guessWrapper p selector targets paragraphs within an element with the ID guessWrapper. It sets the font size to 40px, displays them as inline-block, adds letter spacing, and applies margins for spacing.


The .inside-wrapper class is applied to elements with text centered. The :first-child selector targets the first element with this class and sets its width to 250px. The :last-child selector targets the last element with this class and sets its width to 400px. It also adds padding to the right, aligns the text to the right, and makes it a flex container with a column direction. The div:last-child selector targets the last div within this element and adds a margin to the top to push it to the bottom of the container.


The #wrongLetters ID targets an element and aligns the text to the right.


The #wrongLetters span selector targets spans within the element with the ID wrongLetters and sets the text alignment to the right and the color to a specific shade of red. It also adds letter spacing.


The @media rule specifies styles that will apply when the viewport width is less than or equal to 470px. It modifies the font size, margin, and width of certain elements to make the layout more suitable for smaller screens.


The input selector targets input elements and sets various styles such as border radius, border style, alignment, and transition.


The input:focus selector targets input elements in focus and modifies their appearance by removing the outline and changing the border color.


The button selector targets button elements and sets styles for transition, outline, border style, background color, text color, and border radius. The :hover and :focus selectors modify the appearance of buttons when hovered over or in focus.


Both input and button selectors set padding, box-sizing, and letter spacing to ensure consistent styling.


This will give our hangman game an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: url("https://res.cloudinary.com/dshmwg7vw/image/upload/v1550486966/OCCNFD0.jpg");
  background-size: contain;
  background-repeat: repeat;
  font-family: "Permanent Marker", cursive;
  position: relative;
}

main {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.wrapper,
.button-wrapper {
  text-align: center;
  margin: 10px;
}

.outside-wrapper {
  margin-bottom: 20px;
  text-align:center;
}

.outside-wrapper:nth-child(2) {
  width: 100%;
  margin-top: 20px;
  display: flex;
  justify-content: center;
  max-height: 300px;
}

.outside-wrapper:nth-child(3) {
  margin-bottom: auto;
  height: 178px;
  width: 100%;
}

.hidden {
  display: none;
}

#statusMessage {
  margin-top: 20px;
  margin-bottom: 20px;
  padding: 10px;
  box-sizing: border-box;
  text-align: center;
  height: 94px;
}

svg {
  transform: rotate(-1deg);
}

.lives {
  width: 40px;
  height: auto;
}

.hiddenLife {
  display: inline-block;
  animation: lifeAway 0.6s forwards;
}

@keyframes lifeAway {
  0% {
    opacity: 1;
  }

  10% {
    transform: scale(1.5) rotate(0deg);
  }

  50% {
    transform: scale(0.5) rotate(720deg);
  }

  100% {
    transform: scale(0) rotate(720deg);
    opacity: 0;
    display: none;
  }
}

#categoryName {
  font-size: 20px;
  margin: 0 5px 5px 5px;
}

#warningText {
  color: rgb(239, 83, 80);
}

.warning {
  height: 20px;
}

#guessWrapper p {
  font-size: 40px;
  display: inline-block;
  letter-spacing: 15px;
  margin-bottom: 20px;
  margin-top: 0;
  color: green;
}

.inside-wrapper {
  text-align: center;
}

.inside-wrapper:first-child {
  width: 250px;
}

.inside-wrapper:last-child {
  width: 400px;
  padding-right: 20px;
  box-sizing: border-box;
  text-align: right;
  display: flex;
  flex-direction: column;
}

.inside-wrapper div:last-child {
  margin-top: auto;
}

#wrongLetters {
  text-align: right;
}

#wrongLetters span {
  text-align: right;
  color: rgb(239, 83, 80);
  letter-spacing: 5px;
}

@media (max-width: 470px) {
  #categoryName {
    font-size: 18px;
    margin-bottom: 10px;
  }

  .lives {
    width: 25px;
    height: auto;
  }

  #guessWrapper p {
    font-size: 20px;
  }
}

input {
  border-radius: 7px;
  border-style: none;
  border: 1px solid gray;
  text-align: center;
  transition: 0.2s linear;
}

input:focus {
  outline: none;
  border: 1px solid green;
}

button {
  transition: 0.2s linear;
  outline: none;
  border-style: none;
  background-color: darkgray;
  color: black;
  border-radius: 7px;
}

button:hover,
button:focus {
  background-color: green;
  outline: none;
  color: white;
}

input,
button {
  padding: 5px 10px;
  box-sizing: border-box;
  letter-spacing: 3px;
} 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. The given JavaScript code is an implementation of a Hangman game using vanilla JavaScript. Let's go through the code step by step:


The code is wrapped inside the window.onload event handler, which ensures that the code is executed when the window finishes loading.


Two arrays, wordsArray and categoryArray, are defined. These arrays hold the words to be guessed and their corresponding categories.


The variable newGame is assigned the DOM element with the id "newGame". It represents a button that starts a new game.


An event handler is attached to the onclick event of the newGame button, which calls the startNewGame function when clicked.


The Hangman class is defined using the JavaScript class syntax. It represents the game itself and has various methods for setting up the game, handling user input, checking guesses, and determining game over conditions.


The Hangman class has a constructor that initializes the game state and sets initial values such as a random word to guess, the corresponding category, an array to store the placeholder for the word, an array to store guessed letters, and the number of lives remaining.


The setupNewWord method of the Hangman class is responsible for setting up the game UI when a new word is chosen. It creates and appends elements for displaying the category, the placeholder for the word, and attaches event handlers for user input.


The handleClick method is called when the user clicks the "Guess" button. It retrieves the user's letter input, validates it, and checks whether it matches any letters in the word to guess. It updates the UI accordingly and keeps track of guessed letters and remaining lives.


The handleKeyPress method is called when the user presses a key while focused on the letter input field. If the key pressed is the "Enter" key (keyCode 13), it triggers a click event on the "Guess" button.


The checkGuess function takes the word to guess and the user's letter as arguments. It updates the placeholder array by replacing underscores with the correct letter if the letter matches any in the word.


The gameOver function is called when the game ends, either by winning or losing. It updates the UI to display the game result.


The hangerDraw function is responsible for displaying different parts of the hangman figure as the player makes wrong guesses. It takes a number as an argument and shows the corresponding body part of the hangman.


The hideLives function is called to hide a life indicator when the player makes a wrong guess. It takes a number as an argument and hides the corresponding life element.


The hideElements function is a utility function that hides elements by adding a specified CSS class to them. It takes a class name and a list of elements as arguments.


The unhideElements function is a utility function that shows previously hidden elements by removing a specified CSS class from them. It takes a class name and a list of elements as arguments.


The startNewGame function is called when the "New Game" button is clicked. It resets the game state, clears the UI, and starts a new game by creating an instance of the Hangman class and calling its setupNewWord method.


Finally, an instance of the Hangman class is created and its setupNewWord method is called to start the first game when the window loads.


Create a JavaScript file with the name of script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document, so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.

window.onload = function() {
  let wordsArray = [
    ["C", "A", "T", "S"],
    ["M", "O", "U", "S", "E"],
    ["J", "A", "V", "A", "S", "C", "R", "I", "P", "T"],
    ["P", "O", "T", "A", "T", "O"],
    ["U", "N", "D", "E", "F", "I", "N", "E", "D"],
    ["S", "P", "A", "G", "H", "E", "T"],
    ["W", "A", "Y"]
  ];
  let categoryArray = [
    ["The internet and Youtube would not be the same without them"],
    ["Touchpad ain't got nothing on me"],
    ["Love it or hate it, frontend devs need it"],
    ["This hangman game is..."],
    ["I'm declared, but don't have a value"],
    ["Somebody toucha my..."],
    ["You do not know de..."]
  ];

  let newGame = document.getElementById("newGame");
  newGame.onclick = startNewGame;

  class Hangman {
    constructor() {
      //game state and initial values
      this.random = Math.floor(Math.random() * wordsArray.length);
      this.wordToGuess = wordsArray[this.random];
      this.category = categoryArray[this.random];
      this.placeholderArray = Array(this.wordToGuess.length).fill("_");
      this.guessed = [];
      this.lives = 6;
    }
    setupNewWord() {
      //setsup new game input/buttons and creates initial placeholder containing only "_" and puts it on the board. placeholder has as many characters as the word
      let guessWrapper = document.getElementById("guessWrapper");
      let placeholderP = document.createElement("p");
      let category = document.getElementById("categoryName");
      category.innerHTML = this.category;

      placeholderP.setAttribute("id", "placeholderP");
      placeholderP.innerHTML = this.placeholderArray.join("");
      guessWrapper.appendChild(placeholderP);

      let userLetter = document.getElementById("userLetter");
      userLetter.onkeypress = this.handleKeyPress.bind(this);

      let guessButton = document.getElementById("guessButton");
      guessButton.onclick = this.handleClick.bind(this);
    }
    handleClick() {
      //main game logic, triggers input check, win or loose, updates lives, shows/hides various elements on click
      let userLetterInput = document.getElementById("userLetter");
      let userLetter = userLetterInput.value.toUpperCase();
      let placeholderP = document.getElementById("placeholderP");
      let warningText = document.getElementById("warningText");
      let alreadyGuessed = document.querySelector("#alreadyGuessed span");
      let wrongLetters = document.querySelector("#wrongLetters span");
      let leftLives = document.querySelector("#leftLives span");

      if (!/[a-zA-Z]/.test(userLetter)) {
        //check that the user types in letters
        unhideElements("hidden", warningText);
        warningText.innerHTML = "Please enter a letter from A-Z"; //and shows warning if not
      } else {
        hideElements("hidden", warningText);

        if (
          this.wordToGuess.indexOf(userLetter) > -1 &&
          this.guessed.indexOf(userLetter) == -1
        ) {
          //check if letter is a match, and first guess
          checkGuess(this.wordToGuess, userLetter);
          hideElements("hidden", warningText);
        } else if (
          this.wordToGuess.indexOf(userLetter) == -1 &&
          this.guessed.indexOf(userLetter) == -1
        ) {
          //check if not match, and first wrong
          hideElements("hidden", warningText);
          unhideElements("hidden", wrongLetters.parentNode);
          wrongLetters.innerHTML += userLetter;
          this.lives--;
          hangerDraw(this.lives);
          hideLives(this.lives);
        } else {
          //if not first use of this letter
          unhideElements("hidden", warningText);
          warningText.innerHTML = "";
          warningText.innerHTML += "Already typed " + userLetter;
        }
        this.guessed.indexOf(userLetter) == -1
          ? this.guessed.push(userLetter)
          : null; //for all guesses, if its the first time using the letter, save it

        if (Array.from(placeholderP.innerHTML).indexOf("_") == -1) {
          //trigger game win or loose
          gameOver(true); //when no more '_' exist in placeholder, you win
        } else if (this.lives == 0) {
          //when lives are gone, you loose
          gameOver();
        }
      }
      userLetterInput.value = "";
    }
    handleKeyPress(e) {
      //if enter is pressed trigger click on button
      var guessButton = document.getElementById("guessButton");
      if (e.keyCode === 13) {
        guessButton.click();
      }
    }
  }

  function checkGuess(wordToGuess, userLetter) {
    //handles check logic, and replaces letters in placeholder when a match is found
    let placeholderP = document.getElementById("placeholderP");
    let placeholderArray = Array.from(placeholderP.innerHTML);
    placeholderArray = placeholderArray.map((el, i) => {
      //check if letter exists in the guess word, and if yes,replace it in the placeholder and display it
      if (wordToGuess[i] == userLetter) {
        return (el = userLetter);
      } else {
        return el;
      }
    });

    placeholderP.innerHTML = placeholderArray.join("");
  }

  function gameOver(win) {
    // shows win/game over message
    let winMessage = document.getElementById("statusMessage");
    let btnWrapper = document.querySelector(".button-wrapper");
    hideElements("hidden", btnWrapper);
    if (win) {
      winMessage.innerHTML = "You Win";
      winMessage.style.color = "green";
    } else {
      winMessage.innerHTML = "Game Over";
      winMessage.style.color = "rgb(239, 83, 80)";
    }
  }

  function hangerDraw(num) {
    //helper function triggers show hanger drawing
    let show = document.getElementById(`show${num}`);
    unhideElements("hidden", show);
  }

  function hideLives(num) {
    //helper function triggers hides lives
    let life = document.getElementById(`life${num}`);
    hideElements("hiddenLife", life);
  }

  function hideElements(myclass, ...els) {
    //helper func that hides
    for (let el of els) {
      el.classList.add(myclass);
    }
  }

  function unhideElements(myclass, ...els) {
    //helper func that unhides
    for (let el of els) {
      el.classList.remove(myclass);
    }
  }

  function startNewGame() {
    let btnWrapper = document.querySelector(".button-wrapper");
    let winMessage = document.getElementById("statusMessage");
    let wrongLetters = document.querySelector("#wrongLetters span");
    let warningText = document.querySelector("#warningText");
    let hiddenHangman = Array.from(document.querySelectorAll("svg .bodyPart"));
    let hiddenLives = Array.from(document.querySelectorAll(".lives"));

    for (let bodyPart of hiddenHangman) {
      hideElements("hidden", bodyPart);
    }

    for (let life of hiddenLives) {
      unhideElements("hiddenLife", life);
    }

    wrongLetters.innerHTML = "";
    unhideElements("hidden", btnWrapper);
    hideElements("hidden", wrongLetters.parentNode, warningText);
    winMessage.innerHTML = "Vanilla JavaScript Hangman Game";
    winMessage.style.color = "black";
    let oldP = document.getElementById("placeholderP");
    if (oldP.parentNode) {
      oldP.parentNode.removeChild(oldP);
    }

    let startGame = new Hangman();
    startGame.setupNewWord();
  }

  let startGame = new Hangman(); //initiates first game on windo load
  startGame.setupNewWord();
};

Final Output:

Learn How to Create a Hangman Game using HTML, CSS, and JavaScript.gif

Conclusion:

Congratulations on completing this comprehensive tutorial on building a Hangman Game using HTML, CSS, and JavaScript! Throughout this guide, you have learned the fundamental concepts and techniques necessary to create an interactive and engaging game from scratch.


By following the step-by-step instructions, you have gained hands-on experience in structuring the HTML elements, applying CSS styles to create an appealing visual interface, and implementing the game logic using JavaScript. You have explored how to generate random words, handle user input, update the game state, and check for win or loss conditions.


However, this tutorial is just the beginning of your journey into game development. There are endless possibilities to further enhance and customize your Hangman Game. Consider adding features such as scoring systems, difficulty levels, time limits, or even multiplayer functionality. Don't be afraid to get creative and add your personal touch to make your game stand out.


As you continue to develop your coding skills, keep exploring and experimenting with different techniques and concepts. Online resources, forums, and communities can be valuable assets for expanding your knowledge and exchanging ideas with fellow developers.


Remember, the joy of game development lies not only in building the game but also in sharing it with others. Invite your friends, family, or colleagues to play your Hangman Game and gather their feedback. Their insights can help you improve and refine your creation.


Lastly, always embrace the iterative process of learning and improvement. Take this opportunity to reflect on your journey, identify areas where you can grow, and challenge yourself to tackle more complex projects in the future.


Thank you for joining us on this exciting adventure into building a Hangman Game. We hope this tutorial has sparked your curiosity and passion for game development. Keep coding, exploring, and unleashing your creativity to create amazing games that entertain and engage others. Best of luck on your future endeavors, and happy coding!

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post