Building a Simple Rock–Paper–Scissors Game Using HTML, CSS, and JavaScript

Simple Rock–Paper–Scissors Game Using HTML, CSS, and JavaScript

Rock–Paper–Scissors is one of the best beginner-friendly projects to understand how JavaScript interacts with the DOM, handles events, and updates UI elements.
In this article, we will walk through a fully working implementation of the game using simple logic and clean code.

The goal of the project is to let the user pick Rock, Paper, or Scissors, then let the computer randomly choose its own option, and finally display the result.

Understanding the HTML Structure

The HTML layout contains three main parts:

  1. The result area showing user and CPU hands
  2. The text result (who wins)
  3. The three clickable options
<div class="result_images">
<span class="user_result"><img src="images/rock.png"></span>
<span class="cpu_result"><img src="images/rock.png"></span>
</div>

<div class="result">Let's Play!!</div>
<div class="option_images">
<span class="option_image"><img src="images/rock.png"><p>Rock</p></span>
<span class="option_image"><img src="images/paper.png"><p>Paper</p></span>
<span class="option_image"><img src="images/scissors.png"><p>Scissors</p></span>
</div>

Each option (.option_image) is clickable, and each contains an image and a label.

Selecting Elements in JavaScript

We begin the script by selecting all the elements we will interact with:

const gameContainer = document.querySelector('.container');
const userResult = document.querySelector('.user_result img');
const cpuResult = document.querySelector('.cpu_result img');
const result = document.querySelector('.result');
const optionsImages = document.querySelectorAll('.option_image');

These references allow us to update the UI dynamically (changing images, text, animations).

Adding Click Logic to Each Choice

We loop through each option (rock, paper, scissors), and attach a click event listener:

optionsImages.forEach((image, index) => {
image.addEventListener('click', (e) => {
// logic here
});
});

The index represents:

  • 0 → Rock
  • 1 → Paper
  • 2 → Scissors

This index will be important later to determine the user’s choice.

User Clicks — Start Animation and Reset UI

When a user clicks on an option:

image.classList.add('active');
userResult.src = cpuResult.src = "images/rock.png";
result.textContent = "Wait...";

This resets the hands to the default rock image, gives visual feedback, and shows “Wait…” during the CPU animation.

Then we remove “active” class from other options:

optionsImages.forEach((image2, index2) => {
index !== index2 && image2.classList.remove('active');
});

We also start shaking animation:

gameContainer.classList.add('start');

Step 2: Delay the CPU Choice

The game waits 2.5 seconds before revealing the results:

setTimeout(() => {
gameContainer.classList.remove('start');

Inside this timeout, the real logic happens.

Step 3: Show User’s Real Choice

We extract the image source of what the user clicked:

let imageSrc = e.target.querySelector('img').src;
userResult.src = imageSrc;

Step 4: Generate CPU Random Choice

The CPU picks a random number 0, 1, or 2:

let randomNumber = Math.floor(Math.random() * 3);
let cpuImages = ['images/rock.png','images/paper.png','images/scissors.png'];
cpuResult.src = cpuImages[randomNumber];

The CPU now displays a random hand.

Step 5: Compare User and CPU Values

We convert the options into short values:

let cpuValue = ['R','P','S'][randomNumber];
let userValue = ['R','P','S'][index];

Our outcomes are mapped like this:

let outComes = {
RP:'Cpu',
RS:'User',
PS:'Cpu',
PR:'User',
SR:'Cpu',
SP:'User'
};

Example:

  • RS → Rock beats Scissors → User wins
  • PR → Paper beats Rock → User wins

We get the result:

let outComeValue = outComes[userValue + cpuValue];
result.textContent = userValue === cpuValue ? 'Match Draw' : `${outComeValue} Won`;

If both values are the same, it is a draw.

CSS Animation (Short Explanation)

When the game starts, CSS applies shaking animations:

.container.start .user_result { animation: userShake 0.7s infinite; }
.container.start .cpu_result { animation: cpuShake 0.7s infinite; }

This makes the game feel more alive and fun.

Final Result

With a few lines of JavaScript and CSS animations, we created a fully functional Rock–Paper–Scissors game where:

  • User clicks an option
  • UI animates and resets
  • CPU randomly selects an option
  • JavaScript compares results
  • The game announces a winner

Want to See the Full Code?

I uploaded the complete project to a public repository.
You can check it here:

GitHub Repo


Building a Simple Rock–Paper–Scissors Game Using HTML, CSS, and JavaScript was originally published in Javarevisited on Medium, where people are continuing the conversation by highlighting and responding to this story.

This post first appeared on Read More