How to Create Memory Match Card Game Using HTML, CSS, and Javascript
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
<!DOCTYPE html>
: Declares the document as an HTML5 document.
<html lang="en">
: Starts the HTML document and specifies the language as English.
-
<head>
: Contains metadata and links for the document.
<meta charset="UTF-8">
: Specifies the character encoding as UTF-8, supporting all common characters.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
: Ensures the page is responsive and adapts to different device sizes.
<title>
: Sets the title of the page as "Memory Match Card Game."
-
<link>
: Includes external stylesheets.
- The first link loads Font Awesome icons.
- The second link loads the custom CSS file (
style.css
).
-
<body>
: Contains the content of the page.
-
<div class="game-container">
: A wrapper for the game elements.
<h1>
: Displays the game title.
<div id="game-board">
: A container for the game cards (populated dynamically via JavaScript).
<div id="status">
: Displays the game status, e.g., "Congratulations! You Won!"
<button id="reset-btn">
: A reset button for restarting the game.
<script>
: Links to the JavaScript file (script.js
) that contains the game logic.
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
*
: A universal selector to remove default padding, margins, and set box-sizing for all elements.
-
body
:
display: flex
: Makes the body a flex container.
justify-content: center
: Horizontally centers the content.
align-items: center
: Vertically centers the content.
min-height: 100vh
: Ensures the body takes up the full viewport height.
background-color: #222
: Sets a dark gray background color.
color: #333
: Sets the text color to a lighter gray.
.game-container
: Centers the content.
-
h1
:
margin-bottom: 20px
: Adds spacing below the title.
font-size: 2em
: Increases the font size.
color: white
: Sets the text color to white.
-
#game-board
:
display: grid
: Creates a grid layout for cards.
grid-template-columns: repeat(4, 1fr)
: Creates 4 equal columns.
gap: 15px
: Adds spacing between cards.
width: 400px
: Sets the game board width.
margin: 0 auto 20px
: Centers the board and adds spacing below.
.card
: Styles the individual cards.perspective: 1000px
: Adds a 3D effect for flipping.
-
.card-inner
: Handles the flip animation.
transition
: Smoothens the flip effect.
.flipped
: Adds the rotateY(180deg)
transform when flipped.
-
.card-front, .card-back
: Styles both sides of the card.
backface-visibility: hidden
: Hides the back when the card is not flipped.
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
icons
: List of Font Awesome icons for the game.
board
, status
, resetBtn
: References to DOM elements.
flippedCards
, matchedCards
: Track game state.
iconColors
: Colors for icons.
function shuffle(array)
: Shuffles the icons randomly using the Fisher-Yates algorithm.
function createCard(icon, color)
: Creates a card element dynamically.
function flipCard(card)
: Flip cards handle flipping.
function checkForMatch()
: Handle matching logic and check for matches.
function checkGameOver()
: Check win condition and update game status.
function initGame()
Initialize the game, function resetGame()
: Reset the game and shuffle the board.