JavaScript Tutorial - Create a Card Game 🃏 -

JavaScript Tutorial – Create a Card Game 🃏
Views: 59432
Like: 2385
Improve your JavaScript skills by creating a basic card game with HTML and CSS. ♣️♥️♠️♦️

This tutorial not only covers creating a basic card game using JavaScript
but also:
– how to create dynamic user interactive code using vanilla JavaScript
– Creating some animation effects
– Responsive layout design using CSS grid, CSS FlexBox and media queries
– How to dynamically change the positions of grid cells, so as to randomize the positions of the cards contained in a css grid using JavaScript,
– localStorage functionality
– And much More…

💻 Code:

✏️ Gavin Lon created this tutorial. Check out his channel:

⭐️ Contents ⭐️
⌨️ (0:00:00) Introduction
⌨️ (0:05:26) Getting Started
⌨️ (0:07:00) Live Server Extension
⌨️ (0:09:50) Create Cards – HTML
⌨️ (0:14:44) Create the Game Play Grid
⌨️ (0:19:55) Create Cards Dynamically – JS Code
⌨️ (0:28:46) Initialise Card Positions
⌨️ (0:34:39) Load Game and Start Game
⌨️ (0:38:43) Stack Cards
⌨️ (0:41:53) Flip Cards
⌨️ (0:45:14) Shuffle Cards
⌨️ (0:49:28) Deal Cards
⌨️ (0:54:37) Choose Card
⌨️ (1:16:56) Styling and Layout
⌨️ (1:24:28) Animation
⌨️ (1:32:39) Responsive Layout
⌨️ (1:36:43) Local Storage

🎉 Thanks to our Champion and Sponsor supporters:
👾 Nattira Maneerat
👾 Heather Wcislo
👾 Serhiy Kalinets
👾 Erdeniz Unvan
👾 Justin Hual
👾 Agustín Kussrow
👾 Otis Morgan

Learn to code for free and get a developer job:

Read hundreds of articles on programming:


  1. Thanks for that Tutorial… loved it so much ❤

  2. Thank you so Mucch this was so very enlightening, enjoyed every Minute

  3. Hey hi! i'am trying to make this card game but my card is not flipping. any clue??
    this is my code:

    –card-width: 157px;
    –card-height: 220px;

    margin-top: 30px;
    position: relative;

    position: absolute;
    height: var(–card-height);
    width: var(–card-width);
    perspective: 1000px;
    cursor: pointer;

    position: relative;
    width: 100%;
    height: 100%;
    text-align: center;
    transition: transform 0.6s;
    transform-style: preserve-3d;

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

    .card-front, .card-back{
    position: absolute;
    width: 100%;
    height: 100%;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;


    height: 100%;

    transform: rotateY(180deg);

  4. I created this video primarily to help those interested in web development with their familiarity with JavaScript and associated web development technologies (HTML and CSS). In this video we go through the step by step creation of a basic card game that runs in the users browser which hopefully provides a great context for practicing our JavaScript skills. I hope you enjoy this video and benefit from it. A special thank you to FreeCodeCamp for sharing this video!

  5. Awsome channel….. thank you for support sir❤️

  6. 1st comment!!!
    Viewing when 1min till publish.
    We are all getting better day by day ❤️

  7. I don't really think that the animation is that great..

  8. Guys I need help im new to coding, I want to create io games on websites and websites in generall, what programing languages should I learn? I want learn Python, C#, C++ are these the correct ones?

  9. Your coding style clearly reflects that you are a C# developer on origin Sir 🙂

  10. Great courses but I getta ask, will ChatGPT taking over FCC and other sources? that's a great question to ask ChatGPT.

  11. I have basic knowledge of javascript. Can I go along with this course?

  12. Playing card games is my favourite hobby and JavaScript is one of my favourite languages!

    Thanks so much for this tutorial ❤❤❤

  13. Perfectly explain step by step I really love it

  14. How different would it be if one were to recreate this in C++?

  15. Gavin says he has "many" years of experience but he is very modest. He has nearly two decades of software engineering experience at companies in London. We are proud to have Gavin on the freeCodeCamp team, and excited to publish more of his fun, in-depth courses in the near future. Be sure to subscribe to his channel.

  16. // Define the suits and ranks for a standard deck of cards
    const suits = ['hearts', 'diamonds', 'clubs', 'spades'];
    const ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king', 'ace'];

    // Define a deck of cards as an array of objects, where each object has a suit and a rank
    const deck = [];
    for (let suit of suits) {
    for (let rank of ranks) {
    deck.push({suit, rank});

    // Shuffle the deck using the Fisher-Yates algorithm
    function shuffle(array) {
    for (let i = array.length – 1; i > 0; i–) {
    let j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];

    // Deal five cards to each player
    const player1 = deck.slice(0, 5);
    const player2 = deck.slice(5, 10);

    // Determine the winning hand using standard poker rankings
    function getWinningHand(player) {
    // Check for a straight flush (a straight of the same suit)
    const straightFlush = player.filter(card => card.suit === player[0].suit);
    if (straightFlush.length === 5 && ranks.indexOf(straightFlush[4].rank) – ranks.indexOf(straightFlush[0].rank) === 4) {
    return straightFlush;

    // Check for four of a kind (four cards with the same rank)
    const fourOfAKind = player.filter(card => card.rank === player[0].rank);
    if (fourOfAKind.length === 4) {
    return fourOfAKind;

    // Check for a full house (three of a kind and a pair)
    const threeOfAKind = player.filter(card => card.rank === player[0].rank);
    if (threeOfAKind.length === 3) {
    const remainingCards = player.filter(card => card.rank !== player[0].rank);
    if (remainingCards[0].rank === remainingCards[1].rank) {
    return player;

    // Check for a flush (all cards have the same suit)
    if (player.every(card => card.suit === player[0].suit)) {
    return player;

    // Check for a straight (all cards are in sequential order)
    if (ranks.indexOf(player[4].rank) – ranks.indexOf(player[0].rank) === 4) {
    return player;

    // Check for three of a kind
    if (threeOfAKind.length === 3) {
    return threeOfAKind;

    // Check for two pairs
    if (player.filter(card => card.rank === player[0].rank).length === 2) {
    const remainingCards = player.filter(card => card.rank !== player[0].

  17. Thank you. You provide the best ways to learn programming. You are the best educational content. I hope you add Arabic translation to your courses.

  18. Hello, Im a beginner coder, I am getting a error message that says "no module named pygame".
    what do you suggest I do to fix this?

  19. Hello
    How to write macro for whole directory in epsilon code editor
    For changing numbers in whole directory please reply me

  20. I finished coding a blackjack game from scratch in javascript last week without any guidance, and I have a feeling when I finish watching this I'm gonna feel less satisfied with my effort😂

  21. I'm only 30 minutes into it and I'm noticing my execution of DOM, wasn't too far off. But the fine balance of abstraction and encapsulation here is inspiring.

    For the purpose of enhanced readability and curbing complexity, is it common practice to write many concise functions or fewer in-depth functions.

    For example, my blackjack game required at most 11 functions. But the algorithms were sometimes 10+ lines. Hit, fold, stay, low bet, med bet, high bet, play again, reset, counter, check for aces, and check results. Some were also nested within each other.

    For example, the counter kept track of the sum of a list of integers. A new randomly generated number would be added to the list when the hit button was clicked. Immediately after, the counter function is called where it sums the list and returns the value. But before summing the total, it checks for aces. While doing so it loops through the list and determines if an 11 is present. If so, it checks the new sum and if the new value brings the sum over 21, it changes the 11 to a 1.

    Immediately after running the 'check for aces' function, it sums the list and checks for aces yet again, before running the rest of the hit function which will now create the new element with the appropriate class and id, as well as the src of the image according to the newly generated random value. Conditions for busting are set within the counter function as well.

    But my question is, when does big O notation become problematic. And will the "many simple functions" technique make the computation more efficient?

    It's probably a fairly simple question. But before a month ago, I hadn't known anything about comp sci. I'm actually starting a degree program next month and I've been running off of 4 hours of sleep per day these last few weeks out of pure interest and curiosity.

  22. just fyi: that emmet abbreviation isn't a default thing for everyone

  23. The code "if (shuffleCount == 500) { clearInterval(id) } else { shuffleCount++ }" is a bad practice. When checking a value that changes in a range, you should always use an inequality like "if (shuffleCount < 500 ) { shuffleCount++ } else { clearInterval(id) }". This way when a bug occurs that changes the value being checked outside of the range, you don't get an infinite loop.

  24. ngl making 70 thousand functions made it so hard to follow

  25. Just a comment to boost the signal of the video ❤

  26. No matter what I do "card-img" is a separate child class from "card-front" and "card-back". So the card images never load.. I've been trying to get them to become the same class (or merge) like @32.45 of the video (see <div class="card-front card-img">) but have had no luck. I've even tried copying the same code from github but no luck. Seems like the code is broken to me?

  27. Hi someone know my card dont hace thw flip effect😢

  28. Incredibly confusing for a learner. I'd only recommend this for intermediate coders curious on how someone else solves a problem, I know I'm autistic & maybe dyslexic but the step-by-step explanation is just "Now we'll write the method addCardBackInnerCardToGridMappedToFirstChildStyleElement() and it'll have the method removeCardFromIndexToArrayStatusGameStart()" like 53:01 – I'll try to understand the GItHub code instead of copying from someone copying. I'm so sorry, I'm not trying to be negative, I'm trying to type this in the most neutral way possible! I love you so much & notice how much care you put into this!

  29. wait how do you get the image into the vs code editor?

  30. This is how I did my shuffle function. Seems to give unpredictable random results.

    function randomizeCardPositions() {
    for (let i = cardPositions.length – 1; i >= 0; i–) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = cardPositions[i];
    cardPositions[i] = cardPositions[j];
    cardPositions[j] = temp;

Leave a Reply

Your email address will not be published.