How to Create Memory Match Card Game Using HTML, CSS, and Javascript

Play Game Now Get Source Code

Step 1: HTML


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Memory Match Card Game</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="game-container">
    <h1>Memory Match Game</h1>
    <div id="game-board"></div>
    <div id="status"></div>
    <button id="reset-btn">Reset Game</button>
  </div>
  <script src="script.js"></script>
</body>
</html>
  

HTML Explanation

Step 2: CSS


/* General Reset */
*{
	margin:0;
	padding: 0;
	box-sizing: border-box;
	font-family: Arial, sans-serif;
}
body{
	display:flex;
	justify-content: center;
	align-items: center;
	min-height:100vh;
	background-color: #222;
	color: #333;
}
.game-container{
	text-align: center;
}

h1{
	margin-bottom: 20px;
	font-size: 2em;
	color: white;
}

#game-board{
	display:grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 15px;
	width: 400px;
	margin: 0 auto 20px;
}

.card{
	position: relative;
	width: 100%;
	height: 100px;
	perspective: 1000px;
}
.card-inner{
	position: absolute;
	width: 100%;
	height: 100%;
	transition: transform 0.6s;
	transform-style: preserve-3d;
}

.card.flipped .card-inner{
	transform: rotateY(180deg);
}

.card-front, .card-back{
	position: absolute;
	width: 100%;
	height: 100%;
	backface-visibility: hidden;
	border-radius: 8px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 2em;
}

/*Front of the card - Trump card design */
.card-front{
	background-color: #2c3e50;
	color: #ecf0f1;
	background-image: linear-gradient(135deg, #34495e 25%, transparent 25%),
	linear-gradient(225deg, #34495e, 25%, transparent 25%),
	linear-gradient(45deg, #34495e, 25%, transparent 25%),
	linear-gradient(315deg, #34495e, 25%, #2c3e50 25%);
	background-position: 10px 0, 10px 0, 0 0, 0 0;
	background-size: 20px 20px;
	background-repeat: repeat;
	border: 2px solid #ecf0f1;
}

.card-back{
	background-color: #fff;
	color: #000;
	transform: rotateY(180deg);
}

#status{
	margin-top: 20px;
	font-size: 1.2em;
	font-weight: bold;
	color: #00b894;
}
#reset-btn{
	margin-top: 10px;
	padding: 10px 20px;
	font-size: 1em;
	border: none;
	background-color: #00b894;
	color: white;
	border-radius: 5px;
	cursor: pointer;
	transition: background-color 0.3s ease;
}
#reset-btn:hover{
	background-color: #00a67c
}
  

CSS Explanation

Step 3: JavaScript


//List of font awesome icons for the game
const icons = [
	"fa-heart", "fa-heart", "fa-star", "fa-star", "fa-moon", "fa-moon", "fa-bell", "fa-bell", "fa-car", "fa-car", "fa-cube", "fa-cube", "fa-leaf", "fa-leaf", "fa-smile", "fa-smile"
];

const board = document.getElementById("game-board");
const status = document.getElementById("status");
const resetBtn = document.getElementById("reset-btn");

let flippedCards = [];
let matchedCards = [];
const iconColors = ['#e74c3c', '#f1c40f', '#3498db', '#9b59b6', '#2ecc71', '#e67e22', '#1abc9c', '#ff4757'];

resetBtn.addEventListener("click", resetGame);

//Shuffle function
function shuffle(array){
	for(let i = array.length - 1; i > 0; i--){
		const j = Math.floor(Math.random() * (i + 1));
		[array[i], array[j]] = [array[j], array[i]];
	}
}

//Function to create a card
function createCard(icon, color){
	const card = document.createElement("div");
	card.classList.add("card");
	
	const cardInner = document.createElement("div");
	cardInner.classList.add("card-inner");
	
	const cardFront = document.createElement("div");
	cardFront.classList.add("card-front");
	
	const cardBack = document.createElement("div");
	cardBack.classList.add("card-back");
	cardBack.style.color = color;
	cardBack.innerHTML = '';
	
	cardInner.appendChild(cardFront);
	
	cardInner.appendChild(cardBack);
	card.appendChild(cardInner);
	
	card.addEventListener("click", () => flipCard(card));
	card.dataset.icon = icon;
	
	return card;
}

function flipCard(card){
	if(flippedCards.length === 2 || card.classList.contains("flipped") || card.classList.contains("matched")) return;
	
	card.classList.add("flipped");
	flippedCards.push(card);
	
	if(flippedCards.length === 2)
		checkForMatch();
}

function checkForMatch(){
	const [card1, card2] = flippedCards;
	
	if(card1.dataset.icon === card2.dataset.icon){
		card1.classList.add("matched");
		
		card2.classList.add("matched");
		matchedCards.push(card1, card2);
	}else{
		setTimeout(() => {
			card1.classList.remove("flipped");
			card2.classList.remove("flipped");
		}, 1000);
	}
	
	flippedCards = [];
	checkGameOver();
}

function checkGameOver(){
	if(matchedCards.length === icons.length){
		status.innerText = "Congratulations! You Won!";
	}
}

function initGame(){
	board.innerHTML = "";
	status.innerText = "";
	flippedCards = [];
	matchedCards = [];
	
	const shuffledIcons = [...icons];
	shuffle(shuffledIcons);
	
	shuffledIcons.forEach((icon, index) => {
		const color = iconColors[index % iconColors.length];
		
		const card = createCard(icon, color);
		board.appendChild(card);
	});
}

function resetGame(){
	initGame();
}

//Initialize the game on page load
initGame();

  

Javascript Explanation