Open In App

Build a Memory Card Game Using HTML CSS and JavaScript

Last Updated : 23 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A memory game is a type of game that can be used to test or check the memory of a human being. It is a very famous game. In this game, the player has some cards in front of him and all of them facing down initially. The player has to choose a pair of cards at one time and check whether the faces of both cards are matching or not. If the faces of both cards are the same, then the player can keep those cards face up and continue. Otherwise, the player needs to put the picked cards back face down and continue by selecting other cards. In this article, we are going to build a memory game with the help of HTML, CSS, and JavaScript.

Preview:

cardFlipPreview

Memory Card Game Preview

Technologies Used:

  • HTML
  • CSS
  • JavaScript

Approach:

  • Create a basic structure for you games using the HTML tags like div, heading, paragraph, img etc. with the particular Classes and Ids associated with each one of them.
  • Now, select the elements with the help of class and id CSS selectors to style the elements and make the UI attractive and interactive.
  • After HTML and CSS, its time to get all the required elements inside the JavaScript code and apply logic on them.
  • In JavaScript, we will create an array of objects with the image link, respective alt value and ID for each item of the array.
  • In the next part, a callback function will be created to handle the click event of the cards. This function will handle the card flips whether the flipped card is same or different by removing and ading the classes to the elements.
  • Next, another callback function will be created to handle the Restart Game button click, it will shuffle all the cards and flip them backward again to restart the game.
  • At the end, we will check for the condition where game ends and show the result to the user by using the window.alert() method of JavaScript.

Example: The below example will explain how you can create an memory card game using HTML, CSS and JavaScript:

HTML




<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="UTF-8">
    <meta name="viewport" 
          content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Memory Card Game</title>
</head>
  
<body>
    <div class="container">
        <div id="dynamic-cards" class="game-container">
            <div class="heading-container">
                <h1 class="gfg-heading">
                      GeeksforGeeks
                  </h1>
                <h2 class="game-heading">Click any card to flip it!</h2>
            </div>
            <div class="cards-container">
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="1" 
                        src=
                        alt="HTML Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="2" 
                        src=
                        alt="JavaScript Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="3" 
                        src=
                        alt="CSS Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="4" 
                        src=
                        alt="JavaScript Image" class="card-image">
                </div>
  
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="5" 
                        src=
                        alt="HTML Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="6" 
                        src=
                        alt="VUE Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="7" 
                        src=
                        alt="CSS Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="8" 
                        src=
                        alt="React Image" class="card-image">
                </div>
  
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="9" 
                        src=
                        alt="VUE Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="10"
                        src=
                        alt="Angular Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="11" 
                        src=
                        alt="React Image" class="card-image">
                </div>
                <div class="card">
                    <img 
                        src=
                        class="outline-image">
                    <img id="12"
                        src=
                        alt="Angular Image" class="card-image">
                </div>
            </div>
  
            <div class="progress-container">
                <div class="move-counter">Moves: 0</div>
                <button id="restart" class="restart-button">
                      Restart Game
                  </button>
            </div>
        </div>
    </div>
  
    <script src="script.js"></script>
</body>
  
</html>


CSS




body{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
  
.container{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
}
  
.game-container{
    width: 800px;
    padding: 20px;
    border-radius: 10px;
    row-gap: 15px;
    box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
    background-image: linear-gradient(90deg, #fffbd5, #ccc);
}
  
.cards-container{
    display: grid;
    grid-template-rows: 125px 125px 125px;
    grid-template-columns: 200px 200px 200px 200px;
    grid-gap: 20px 10px;
    place-items: center;
}
  
.heading-container{
    text-align: center;
}
  
.gfg-heading{
    color: #0E9D57;
}
  
.card{
    justify-items: center;
    display: flex;
    align-items: center;
    position: relative;
    cursor: pointer;
}
  
.outline-image{
    position: absolute;
    border-radius: 10px;
    top: 0;
    left: 0;
    height: 125px;
    width: 125px;
    border-radius: 50%;
}
  
.card-image{
    height: 125px;
    width: 125px;
    transform: rotateY(90deg); 
    transition: all ease-in 0.25s;
    mix-blend-mode: multiply;
}
  
.progress-container{
    text-align: center;
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin: 50px 0 20px 0;
}
  
.move-counter{
    padding: 10px 20px;
    border-radius: 25px;
    border: 1px solid #ccc;
}
  
.restart-button{
    padding: 10px 20px;
    background-color: #0E9D57;
    border: none;
    border-radius: 25px;
    color: #fff;
    cursor: pointer;
}
  
.restart-button:hover{
    background-color: transparent;
    border: 1px solid #0E9D57;
    color: #0E9D57;
}
  
/* Dynamic classes that are being added by JavaScript */
.toggled .card-image { 
    transform: rotateY(0deg); 
    transition-delay: 0.25s; 
  
.item .outline-image { 
    transition: all ease-in 0.25s; 
    transition-delay: 0.25s; 
    
.toggled .outline-image { 
    transform: rotateY(90deg); 
    transition-delay: 0s; 
}
  
@media screen and (max-width: 767px) {
    .game-container{
        width: 100%;
    }
      
    .cards-container{
        grid-template-rows: 125px 125px 125px 125px;
        grid-template-columns: 33% 33% 33%;
        grid-gap: 10px 10px;
    }
  
    .outline-image{
        height: 100px;
        width: 100px;
    }
      
    .card-image{
        height: 100px;
        width: 100px;
    }
  
    .progress-container{
        margin: 10px 0 10px 0;
    }
      
}


Javascript




const cards = 
    document.getElementsByClassName('card');
let allImages = document.getElementsByClassName('card-image');
let movesDisplay = document.querySelector('.move-counter');
let toggledCardsArray = [];
let move = 0;
let winCount = 0;
const restart = document.getElementById('restart');
  
const imagesLinkArray = [
    {
        id: 1,
        image: 
        newAlt: 'Angular Image'
    },
    {
        id: 2,
        image: 
        newAlt: 'HTML Image'
    },
    {
        id: 3,
        image: 
        newAlt: 'JavaScript Image'
    },
    {
        id: 4,
        image: 
        newAlt: 'React Image'
    },
    {
        id: 5,
        image: 
        newAlt: 'Vue Image'
    },
    {
        id: 6,
        image: 
        newAlt: 'JavaScript Image'
    },
    {
        id: 7,
        image: 
        newAlt: 'Vue Image'
    },
    {
        id: 8,
        image: 
        newAlt: 'HTML Image'
    },
    {
        id: 9,
        image: 
        newAlt: 'CSS Image'
    },
    {
        id: 10,
        image: 
        newAlt: 'Angular Image'
    },
    {
        id: 11,
        image: 
        newAlt: 'CSS Image'
    },
    {
        id: 12,
        image: 
        newAlt: 'React Image'
    }
]
  
// function to restart the game
const restartGame = () => {
    let toggledCard = 
        document.getElementsByClassName('card toggled');
    imagesLinkArray.sort(() => Math.random() - 0.5);
    Object.values(toggledCard).forEach(function (el) {
        setTimeout(() => {
            el.classList.remove("toggled");
        }, 0);
    })
    toggledCardsArray.length = 0;
    move = 0;
    winCount=0;
    movesDisplay.innerText = `Moves: ${move}`;
    let allImagesSrc = document.getElementsByClassName('card-image');
    Object.values(allImagesSrc).forEach((el, index)=>{
        el.src = imagesLinkArray[index].image;
        el.alt = imagesLinkArray[index].newAlt;
        el.id = imagesLinkArray[index].id
    }) 
}
restart.addEventListener('click', restartGame);
  
//checking for the last clicked and current 
//clicked cards and applying changes accordingly
for (var i = 0; i < cards.length; i++) {
    cards[i].addEventListener('click', function () {
        this.classList.add("toggled");
        toggledCardsArray.push(this);
        let thisImgSrc = this.querySelector('.card-image').src;
        let previousImgSrc = 
        toggledCardsArray[toggledCardsArray.length - 2].querySelector('.card-image').src;
        if(thisImgSrc !== previousImgSrc) {
            toggledCardsArray.forEach(function (el) {
                setTimeout(() => {
                    el.classList.remove("toggled");
                }, 500);
            })
            toggledCardsArray.length = 0;
            move++;
        }
        else{
            toggledCardsArray.length = 0;
            move++;
            winCount++;
        }
        movesDisplay.innerText = `Moves: ${move}`;
        if(winCount===6){
            setTimeout(()=>{
                alert(`Congratulations!!! You won the game in ${move} moves.`)
            }, 300)
        }
    })
}


Output: The below output will show you a demo of the above card game:

memoryCardGamePreviewGif



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads