Build an Interactive Quiz Game

Build a trivia quiz game with HTML, CSS, and JavaScript from scratch.

Introduction

30 Second Summary

Quizzes are everywhere online. From personality tests to trivia games, they all work the same way under the hood: questions appear, you click answers, and the page responds instantly without reloading.

In this project, you will build an interactive quiz game from scratch using HTML, CSS, and JavaScript. You'll create animated question cards, clickable answer buttons with color feedback, and a live progress bar.

What You'll Build

A 5-question trivia game with animated slide transitions, color-coded answer feedback, and a progress bar that runs entirely in the browser.

By the end of this project, you'll have:

  • A fully functional quiz game with animated question cards that slide between questions and flash green or red based on your answers.
  • Hand-written HTML, CSS, and JavaScript files that you understand line-by-line.
  • A working knowledge of DOM manipulation, event listeners, and CSS animations that transfers to any future web project.
  • Secret Mission: Add a countdown timer to each question that auto-advances when time runs out.

Are there any prerequisites?

None. This guide walks you through installing and verifying every tool you need. All you need is a computer with internet access.

Set Up Your Project

Every web page is built from three core files working together. HTML defines the structure, CSS handles the styling, and JavaScript controls the interactivity.

In this step, you'll create a dedicated project folder on your Desktop and set up these three files as the foundation of your quiz game.

In this step, get ready to:
  • Create a quiz-game folder on your Desktop.
  • Open the folder as your VS Code workspace.
  • Create three empty project files: index.html, style.css, and script.js.
Create your project folder

Keeping your project in its own folder makes it easy to find and keeps all related files together. You'll create this folder on your Desktop so it's always one click away.

  • In VS Code, open the integrated terminal by clicking Terminal in the top menu bar, then clicking New Terminal.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder by running this command:
mkdir quiz-game
  • Confirm the folder exists by running:
ls

You should see quiz-game listed in the output.

Don't see quiz-game in the output?

Make sure you ran cd ~/Desktop first. If you skipped that step, mkdir created the folder in a different location.

If you see an error saying the folder already exists, that's fine. It means quiz-game is already on your Desktop and ready to use.

help me find where my quiz-game folder was created

Now you'll open this folder as your VS Code workspace so all your project files live in one place.

  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the quiz-game folder, then click Open.

Seeing a trust dialog?

VS Code may ask "Do you trust the authors of the files in this folder?" when you open a new folder. Click Yes, I trust the authors to continue. This enables full VS Code functionality for your project.

Your VS Code Explorer panel on the left should now show the quiz-game folder name at the top. The folder is empty for now.

Create your project files

Your quiz game needs three files. Each has a specific job: one for structure, one for styling, and one for logic.

  • In the Explorer panel on the left side of VS Code, hover over the QUIZ-GAME heading.
  • Click the New File icon (it looks like a page with a small plus sign).
  • Type index.html and press Enter.
  • Click the New File icon again.
  • Type style.css and press Enter.
  • Click the New File icon one more time.
  • Type script.js and press Enter.

What does each file do?

  • index.html holds the quiz structure: headings, buttons, and containers.
  • style.css controls how everything looks: colors, layout, and animations.
  • script.js makes the quiz interactive: tracking scores, switching questions, and responding to clicks.
  • Confirm all three files exist by opening the terminal (Terminal > New Terminal) and running:
ls

You should see index.html, style.css, and script.js listed in the output.

Don't see all three files?

Check the Explorer panel for typos. File names must be exactly index.html, style.css, and script.js with no extra spaces or capital letters.

If a file has the wrong name, right-click it in the Explorer panel and select Rename to fix it.

help me fix my project file names

Your workspace is ready. Next up, you'll fill index.html with the HTML structure that defines your quiz screens, buttons, and progress bar.

Build the HTML Structure

Your quiz game needs three distinct screens: a start screen to welcome the player, a question screen to display questions and answers, and a results screen to show the final score.

In this step, you will write the full HTML structure that defines all three screens inside a single container. You will also link your CSS and JavaScript files so they are ready for later steps.

In this step, get ready to:
  • Write the HTML boilerplate and build the start screen with a heading and button.
  • Add the question screen with a progress bar, question text, and answer buttons.
  • Add the results screen and launch Live Server to preview your page.
Write the HTML boilerplate and start screen

Every HTML page starts with a boilerplate that tells the browser what type of document it is and what resources to load. Your start screen will be the first thing players see when the quiz loads.

  • Open index.html in VS Code by clicking on it in the Explorer sidebar.
  • Copy the following code into the file:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quiz Game</title>
    <!-- Link our stylesheet -->
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="quiz-container">
        <!-- Start Screen -->
        <div id="start-screen" class="screen active">
            <h1 class="title">Quiz Game</h1>
            <p class="subtitle">Test your knowledge!</p>
            <button id="start-btn" class="btn btn-start">Start Quiz</button>
        </div>

What does this code do?

The <head> section loads your stylesheet with a <link> tag so CSS styles will apply when you write them later.

The quiz-container div wraps all three screens. Only the screen with the active class will be visible at a time. JavaScript will toggle this class to switch between screens.

The start screen has an id attribute (start-screen) so JavaScript can find it, and a class attribute (screen active) so CSS can style and show it.

  • Save index.html.
  • You will not see a change in the browser yet. The next chunks add the remaining screens, and then you will launch Live Server to preview everything together.
Add the question screen

The question screen is the core of the quiz. It shows a progress bar at the top, the current question, and four answer buttons arranged in a grid.

  • In index.html, place your cursor directly after the closing </div> of the start screen (the one after the Start Quiz button).
  • Copy the following code below it:
        <!-- Question Screen -->
        <div id="question-screen" class="screen">
            <div class="progress-bar">
                <div id="progress-fill" class="progress-fill"></div>
            </div>
            <div id="question-card" class="question-card">
                <h2 id="question-text" class="question-text"></h2>
                <div class="answers-grid">
                    <button class="btn btn-answer" data-index="0"></button>
                    <button class="btn btn-answer" data-index="1"></button>
                    <button class="btn btn-answer" data-index="2"></button>
                    <button class="btn btn-answer" data-index="3"></button>
                </div>
            </div>
        </div>

What does this code do?

The progress-bar div is a container with a nested progress-fill div inside it. JavaScript will change the width of progress-fill as the player answers questions.

The question-text heading starts empty. JavaScript will fill it with each question's text dynamically.

Each answer button has a data-index attribute (0 through 3). This is a custom HTML data attribute that JavaScript reads to identify which answer was clicked.

  • Save index.html.
  • You still will not see a visual change yet. The next chunk adds the final screen and closes the document.
Add the results screen and launch Live Server

The results screen shows the player's final score after all questions are answered. It also includes a restart button so they can play again.

  • In index.html, place your cursor directly after the closing </div> of the question screen.
  • Copy the following code below it to add the results screen, close the container, and link the JavaScript file:
        <!-- Results Screen -->
        <div id="results-screen" class="screen">
            <h2 class="results-title">Quiz Complete!</h2>
            <p id="score-text" class="score-text"></p>
            <button id="restart-btn" class="btn btn-start">Play Again</button>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

What does this code do?

The results screen follows the same pattern as the start screen. It has an id for JavaScript to find it and a screen class for CSS to style it. It does not have the active class, so it starts hidden.

The <script> tag at the bottom of <body> loads your JavaScript file. Placing it here ensures the HTML is fully loaded before the script runs.

  • Save index.html.
  • In the Explorer sidebar, right-click on index.html.
  • Select Open with Live Server.
  • Your browser opens automatically. You should see the text "Quiz Game", "Test your knowledge!", and a "Start Quiz" button on a plain white page.

Why does the page look unstyled?

Your style.css file is still empty. The browser displays the raw HTML with its default styling. The question and results screens are hidden because they lack the active class. You will add all the styling in the next step.

Don't see Open with Live Server?

Make sure you are right-clicking index.html in the Explorer panel (the file list on the left), not in the "Open Editors" section at the top.

If the option still does not appear, click the Go Live button in the bottom status bar of VS Code instead.

Help me troubleshoot why Live Server is not starting.

✔️ Awesome, I've got everything!

Great. Double check you have saved index.html and your browser is showing the start screen text.

ⓧ I'd like to double check the full code

Here is the complete index.html file. Make sure yours matches exactly:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quiz Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="quiz-container">
        <!-- Start Screen -->
        <div id="start-screen" class="screen active">
            <h1 class="title">Quiz Game</h1>
            <p class="subtitle">Test your knowledge!</p>
            <button id="start-btn" class="btn btn-start">Start Quiz</button>
        </div>

        <!-- Question Screen -->
        <div id="question-screen" class="screen">
            <div class="progress-bar">
                <div id="progress-fill" class="progress-fill"></div>
            </div>
            <div id="question-card" class="question-card">
                <h2 id="question-text" class="question-text"></h2>
                <div class="answers-grid">
                    <button class="btn btn-answer" data-index="0"></button>
                    <button class="btn btn-answer" data-index="1"></button>
                    <button class="btn btn-answer" data-index="2"></button>
                    <button class="btn btn-answer" data-index="3"></button>
                </div>
            </div>
        </div>

        <!-- Results Screen -->
        <div id="results-screen" class="screen">
            <h2 class="results-title">Quiz Complete!</h2>
            <p id="score-text" class="score-text"></p>
            <button id="restart-btn" class="btn btn-start">Play Again</button>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

Your HTML structure is complete. Next up, you will bring it to life with CSS styling, colors, and animations.

Style the Quiz with CSS

Your HTML structure is in place, but right now the page looks like unstyled text on a blank background. CSS transforms that raw structure into a polished, dark-themed quiz card that feels like a real app.

In this step, you'll center the quiz on screen with Flexbox, add smooth hover effects with CSS transitions, and create slide animations with keyframes.

In this step, get ready to:
  • Style the page layout and quiz container card.
  • Add button hover effects and a progress bar with smooth transitions.
  • Create keyframe animations for sliding question cards in and out.
Set up base styles and the quiz container

Every CSS file starts by resetting browser defaults so elements look the same across Chrome, Firefox, and Edge. From there, you'll center the page content and create the card that holds the quiz.

  • Switch back to style.css in VS Code and add the following base styles:
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #1a1a2e;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

.quiz-container {
    background-color: #16213e;
    border-radius: 20px;
    padding: 40px;
    width: 500px;
    max-width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.screen {
    display: none;
    text-align: center;
}

.screen.active {
    display: block;
}

What does this code do?

  • The * selector removes default margins and padding from every element, giving you a clean slate.
  • The body uses display: flex with justify-content: center and align-items: center to center the quiz both horizontally and vertically.
  • The .quiz-container creates a rounded card with a soft shadow that floats over the dark background.
  • The .screen and .screen.active classes let JavaScript show one screen at a time by toggling the active class.
  • Save style.css.
  • Check your browser. You should see a dark page with a centered dark card showing the "Quiz Game" heading and "Start Quiz" button in plain white text.

Still seeing unstyled text on a white page?

Make sure your <link rel="stylesheet" href="style.css"> tag in index.html spells the filename exactly as style.css (lowercase, no extra spaces).

Also confirm that style.css is in the same folder as index.html, not inside a subfolder.

help me debug my CSS not loading

Now add the start screen styles below your existing code. These give the title its signature red color and a smooth entrance animation.

  • Add the following CSS below the .screen.active rule:
/* Start Screen */
.title {
    color: #e94560;
    font-size: 2.5rem;
    margin-bottom: 10px;
    animation: fadeInDown 0.6s ease;
}

.subtitle {
    color: #a8a8b3;
    font-size: 1.1rem;
    margin-bottom: 30px;
}

@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

What does this code do?

  • The .title class gives the heading its red color and attaches the fadeInDown animation.
  • The @keyframes fadeInDown block defines the animation itself. It starts invisible and 20px above, then slides down to its final position over 0.6 seconds.
  • The transform: translateY(-20px) property moves the element vertically without triggering expensive page reflows.

What is a CSS keyframe animation?

A @keyframes rule defines a sequence of styles that an element transitions through over time. You give it a name (like fadeInDown), then reference that name in the animation property of any element.

The from and to keywords define the start and end states. The browser handles all the in-between frames automatically.

  • Save style.css and check your browser.
  • You should see the "Quiz Game" title in red that fades in from above, gray subtitle text, and the plain "Start Quiz" button below.

Title not animating?

Make sure the @keyframes fadeInDown block is placed after the .subtitle rule. Also check that the name in animation: fadeInDown exactly matches the name after @keyframes.

help me debug my CSS animation

Style buttons and the progress bar

CSS transitions let you animate property changes smoothly without writing a full keyframe animation. You'll use them here to make buttons scale up on hover and the progress bar fill smoothly.

  • Add the following button styles below your @keyframes fadeInDown block:
/* Buttons */
.btn {
    border: none;
    border-radius: 12px;
    padding: 15px 30px;
    font-size: 1rem;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.3s ease;
}

.btn:hover {
    transform: scale(1.05);
}

.btn-start {
    background-color: #e94560;
    color: white;
    font-size: 1.2rem;
    padding: 18px 40px;
}

.btn-start:hover {
    background-color: #d63851;
}

What does this code do?

  • The transition property tells the browser to smoothly animate transform and background-color whenever they change, instead of snapping instantly.
  • The transform: scale(1.05) on hover makes the button grow slightly, giving a satisfying "press me" feel.
  • The .btn-start class applies the red brand color and larger padding specifically to the Start and Restart buttons.

Transitions vs keyframes: when to use each

Transitions animate between two states (like normal to hovered). They're perfect for hover effects and simple state changes.

Keyframe animations define multi-step sequences that can loop, reverse, and play on page load. Use them when you need entrance effects or complex motion.

  • Save style.css and hover your mouse over the "Start Quiz" button.
  • The button should smoothly grow when you hover and darken slightly. It should be red with white text.

Button not changing on hover?

Check that your .btn:hover rule uses a colon before hover, not a dot. Also confirm the transition property is on the base .btn rule, not on the hover rule.

help me fix my CSS hover effect

Next, add the progress bar. This bar will visually fill as the player answers questions, with the width animated smoothly by CSS.

  • Add the following progress bar styles below .btn-start:hover:
/* Progress Bar */
.progress-bar {
    background-color: #0f3460;
    border-radius: 10px;
    height: 10px;
    margin-bottom: 30px;
    overflow: hidden;
}

.progress-fill {
    background-color: #e94560;
    height: 100%;
    width: 0%;
    border-radius: 10px;
    transition: width 0.4s ease;
}

What does this code do?

  • The .progress-bar is the outer track. Its overflow: hidden clips the inner fill so it never spills outside the rounded container.
  • The .progress-fill starts at width: 0% and JavaScript will increase it as the player progresses. The transition: width 0.4s ease makes each width change animate smoothly.
  • Save style.css.
  • You won't see the progress bar yet because the question screen is hidden. That's expected. The next chunk will style the question card that lives on the same screen.
Create slide animations and answer button states

When the player answers a question, the card needs to slide out and a new one slides in. You'll define two keyframe animations for this movement, plus visual states that flash buttons green or red.

  • Add the following question card and animation styles below your .progress-fill rule:
/* Question Card */
.question-card {
    animation: slideIn 0.4s ease;
}

.question-card.slide-out {
    animation: slideOut 0.3s ease forwards;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes slideOut {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(-30px);
    }
}

.question-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 25px;
    line-height: 1.4;
}

What does this code do?

  • The slideIn animation starts the card 30px to the right and invisible, then slides it into place. This plays every time a new question appears.
  • The slideOut animation moves the current card 30px to the left and fades it out. The forwards keyword keeps the card hidden after the animation finishes.
  • JavaScript toggles the slide-out class to trigger the exit animation before loading the next question.
  • Save style.css.
  • You won't see these animations in action yet because the question screen is still hidden. You'll see them working after you add JavaScript in the next step.

Now add the answer grid layout and the button feedback states. These styles control what the player sees when they click a correct or wrong answer.

  • Add the following styles below .question-text:
/* Answers Grid */
.answers-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.btn-answer {
    background-color: #0f3460;
    color: #ffffff;
    padding: 18px 15px;
    text-align: center;
}

.btn-answer:hover {
    background-color: #1a4a7a;
}

.btn-answer.correct {
    background-color: #27ae60;
    transform: scale(1.05);
}

.btn-answer.wrong {
    background-color: #e74c3c;
    transform: scale(0.95);
}

.btn-answer:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

.btn-answer:disabled:hover {
    transform: none;
}

What does this code do?

  • The .answers-grid uses CSS Grid with grid-template-columns: 1fr 1fr to create a 2x2 layout for the four answer buttons.
  • The .correct class turns a button green and scales it up slightly. The .wrong class turns a button red and shrinks it slightly.
  • The :disabled styles prevent hover effects on buttons after the player has answered, so only one click registers per question.
  • Save style.css.
  • You won't see the answer grid yet because it's on the hidden question screen. The next chunk adds the final styles for the results screen.

Finally, add the results screen styles to complete your stylesheet.

  • Add the following styles at the bottom of style.css:
/* Results Screen */
.results-title {
    color: #e94560;
    font-size: 2rem;
    margin-bottom: 20px;
    animation: fadeInDown 0.6s ease;
}

.score-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 30px;
}

What does this code do?

The .results-title reuses the same fadeInDown animation from the start screen title. This is one benefit of named keyframes. You define an animation once and attach it to any element.

The .score-text styles the final score message in white with spacing below it for the restart button.

  • Save style.css and check your browser.
  • You should see the styled start screen: a dark card centered on the page, the red "Quiz Game" title with its fade-in animation, gray subtitle, and a red "Start Quiz" button that scales up when you hover.

Start button not red or not centered?

Check that your .btn-start rule has background-color: #e94560. If the container isn't centered, confirm your body rule includes both display: flex and min-height: 100vh. Without the height, Flexbox has nothing to center against vertically.

help me fix my quiz container centering

✔️ Awesome, I've got everything!

Great. Double check you've saved style.css and confirm the start screen looks polished in your browser before moving on.

ⓧ I'd like to double check the full code

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #1a1a2e;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

.quiz-container {
    background-color: #16213e;
    border-radius: 20px;
    padding: 40px;
    width: 500px;
    max-width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.screen {
    display: none;
    text-align: center;
}

.screen.active {
    display: block;
}

/* Start Screen */
.title {
    color: #e94560;
    font-size: 2.5rem;
    margin-bottom: 10px;
    animation: fadeInDown 0.6s ease;
}

.subtitle {
    color: #a8a8b3;
    font-size: 1.1rem;
    margin-bottom: 30px;
}

@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Buttons */
.btn {
    border: none;
    border-radius: 12px;
    padding: 15px 30px;
    font-size: 1rem;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.3s ease;
}

.btn:hover {
    transform: scale(1.05);
}

.btn-start {
    background-color: #e94560;
    color: white;
    font-size: 1.2rem;
    padding: 18px 40px;
}

.btn-start:hover {
    background-color: #d63851;
}

/* Progress Bar */
.progress-bar {
    background-color: #0f3460;
    border-radius: 10px;
    height: 10px;
    margin-bottom: 30px;
    overflow: hidden;
}

.progress-fill {
    background-color: #e94560;
    height: 100%;
    width: 0%;
    border-radius: 10px;
    transition: width 0.4s ease;
}

/* Question Card */
.question-card {
    animation: slideIn 0.4s ease;
}

.question-card.slide-out {
    animation: slideOut 0.3s ease forwards;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes slideOut {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(-30px);
    }
}

.question-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 25px;
    line-height: 1.4;
}

/* Answers Grid */
.answers-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.btn-answer {
    background-color: #0f3460;
    color: #ffffff;
    padding: 18px 15px;
    text-align: center;
}

.btn-answer:hover {
    background-color: #1a4a7a;
}

.btn-answer.correct {
    background-color: #27ae60;
    transform: scale(1.05);
}

.btn-answer.wrong {
    background-color: #e74c3c;
    transform: scale(0.95);
}

.btn-answer:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

.btn-answer:disabled:hover {
    transform: none;
}

/* Results Screen */
.results-title {
    color: #e94560;
    font-size: 2rem;
    margin-bottom: 20px;
    animation: fadeInDown 0.6s ease;
}

.score-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 30px;
}

Your quiz now has a polished visual design with smooth transitions ready to fire. Next up, you'll write the JavaScript that makes the quiz actually playable.

Add JavaScript Game Logic

Your quiz has a beautiful structure and polished styling. Now it needs a brain.

In this step, you'll write the JavaScript that brings your quiz to life. This means storing the questions as data, reading button clicks, showing feedback, and moving through screens. Every interactive website uses this same pattern of listening for user actions and updating what's on screen in response.

In this step, get ready to:
  • Define quiz questions as structured data that JavaScript can loop through.
  • Write functions that display questions, check answers, and show results.
  • Wire up button clicks so the quiz responds to user interaction.
Define your quiz data as an array of objects

Every quiz needs questions. Instead of scattering question text across your HTML, you store all questions in a single JavaScript data structure. This makes it easy to loop through them, add more later, or even load them from an external source.

  • Switch to script.js in VS Code. The file is currently empty.
  • Add the quiz data array by pasting this code:
// Quiz Data
const quizData = [
    {
        question: "What does HTML stand for?",
        answers: ["Hyper Text Markup Language", "High Tech Modern Language", "Home Tool Markup Language", "Hyperlinks and Text Markup Language"],
        correct: 0
    },
    {
        question: "Which CSS property is used to change the text color?",
        answers: ["font-color", "text-color", "color", "foreground-color"],
        correct: 2
    },
    {
        question: "Which symbol is used for single-line comments in JavaScript?",
        answers: ["/* */", "//", "#", "--"],
        correct: 1
    },
    {
        question: "What does CSS stand for?",
        answers: ["Creative Style Sheets", "Cascading Style Sheets", "Computer Style Sheets", "Colorful Style Sheets"],
        correct: 1
    },
    {
        question: "Which HTML tag is used to create a hyperlink?",
        answers: ["<link>", "<href>", "<a>", "<url>"],
        correct: 2
    }
];

What does this code do?

This creates an array called quizData where each item is an object representing one question. Each object has three properties:

  • question holds the question text as a string.
  • answers is an array of four possible answer strings.
  • correct stores the index (starting from 0) of the correct answer in that array.

You won't see a change in the browser yet. The next chunk will connect this data to the page.

  • Below the quiz data array, add state variables and DOM element references by pasting this code:
// State Variables
let currentQuestion = 0;
let score = 0;

// DOM Elements
const startScreen = document.querySelector("#start-screen");
const questionScreen = document.querySelector("#question-screen");
const resultsScreen = document.querySelector("#results-screen");
const startBtn = document.querySelector("#start-btn");
const questionText = document.querySelector("#question-text");
const answerButtons = document.querySelectorAll(".btn-answer");
const progressFill = document.querySelector("#progress-fill");
const questionCard = document.querySelector("#question-card");
const scoreText = document.querySelector("#score-text");
const restartBtn = document.querySelector("#restart-btn");

What does this code do?

The state variables track where the player is in the quiz. currentQuestion remembers which question they're on, and score counts how many they've gotten right.

The DOM element lines use document.querySelector() to grab references to HTML elements by their ID or class. Storing these in variables means you don't have to search the page every time you want to update something.

  • Save script.js.
  • In your browser, right-click the page and select **Inspect**, then click the **Console** tab.
  • Type quizData.length and press **Enter**. You should see 5 printed, confirming your data loaded correctly.

Seeing an error in the console?

  • If you see a red error message when the page loads, check for missing commas between objects in your array or mismatched brackets.
  • Make sure every string uses matching quote marks (opening and closing).
  • If quizData.length returns undefined, double-check that the <script src="script.js"></script> tag is at the bottom of your HTML body.

Help me debug a JavaScript console error in my quiz game.

Write functions to start the quiz and display questions

With your data and DOM references ready, you can write the functions that control the game flow. Each function has one job: starting the quiz, showing a question, or handling an answer.

  • Below your DOM element references in script.js, add the startQuiz function:
// Start Quiz
function startQuiz() {
    currentQuestion = 0;
    score = 0;
    startScreen.classList.remove("active");
    questionScreen.classList.add("active");
    showQuestion();
}

What does this code do?

This function resets the game state (question index back to 0, score back to 0), hides the start screen by removing the active class, and reveals the question screen by adding it. The active class controls which screen is visible using the CSS you wrote earlier.

You won't see a change yet. The startQuiz function calls showQuestion(), which you'll write next.

  • Below the startQuiz function, add the showQuestion function:
// Display Current Question
function showQuestion() {
    const data = quizData[currentQuestion];
    questionText.textContent = data.question;

    answerButtons.forEach(function(button, index) {
        button.textContent = data.answers[index];
        button.classList.remove("correct", "wrong");
        button.disabled = false;
    });

    // Update progress bar
    const progress = (currentQuestion / quizData.length) * 100;
    progressFill.style.width = progress + "%";

    // Trigger slide-in animation
    questionCard.classList.remove("slide-out");
    questionCard.style.animation = "none";
    questionCard.offsetHeight; // Force reflow to restart animation
    questionCard.style.animation = "";
}

What does this code do?

This function pulls the current question from quizData and updates the page. It sets the question text, fills each button with an answer option, and resets any leftover feedback classes from the previous question.

The progress bar width is calculated as a percentage of how far through the quiz you are. The last three lines force the slide-in animation to replay by briefly removing and re-triggering it.

  • Save script.js.
  • In the browser console, type startQuiz() and press **Enter**.
  • You should see the start screen disappear and the first question appear with four answer buttons filled in.

Question screen not appearing?

  • If you see an error like showQuestion is not defined, make sure the showQuestion function is placed above the console call (below startQuiz).
  • If the buttons appear but show no text, check that your answerButtons.forEach loop uses data.answers[index] with the correct variable name.

Help me fix my showQuestion function that isn't displaying the question.

  • Below the showQuestion function, add the selectAnswer function that handles what happens when a player clicks an answer:
// Handle Answer Selection
function selectAnswer(event) {
    const selectedIndex = Number(event.target.dataset.index);
    const correctIndex = quizData[currentQuestion].correct;

    // Disable all buttons
    answerButtons.forEach(function(button) {
        button.disabled = true;
    });

    // Show correct/wrong feedback
    if (selectedIndex === correctIndex) {
        event.target.classList.add("correct");
        score++;
    } else {
        event.target.classList.add("wrong");
        answerButtons[correctIndex].classList.add("correct");
    }

    // Advance after delay
    setTimeout(function() {
        currentQuestion++;
        if (currentQuestion < quizData.length) {
            questionCard.classList.add("slide-out");
            setTimeout(function() {
                showQuestion();
            }, 300);
        } else {
            showResults();
        }
    }, 1000);
}

What does this code do?

When a player clicks an answer button, this function reads which button was clicked using event.target.dataset.index. It compares that to the correct answer index from the quiz data.

All buttons get disabled immediately to prevent double-clicking. If the answer is correct, the button turns green and the score increases. If wrong, the clicked button turns red and the correct answer is highlighted green.

After a 1-second delay (so the player can see the feedback), the function advances to the next question with a slide-out animation. If there are no more questions, it calls showResults() instead.

You won't see a change yet. The next substep will wire this function to button clicks.

Wire up results and event listeners

Your game functions exist but nothing triggers them yet. You need the results screen function, a restart function, and event listeners that connect button clicks to your code.

  • Below the selectAnswer function, add the showResults function:
// Show Results
function showResults() {
    questionScreen.classList.remove("active");
    resultsScreen.classList.add("active");
    scoreText.textContent = "You scored " + score + " out of " + quizData.length + "!";
    progressFill.style.width = "100%";
}

What does this code do?

This hides the question screen, shows the results screen, and builds a message displaying the player's final score. It also fills the progress bar to 100% to show the quiz is complete.

You won't see a change yet. The event listeners in the next chunk will make everything clickable.

  • Below showResults, add the restart function and all the event listeners:
// Restart Quiz
function restartQuiz() {
    resultsScreen.classList.remove("active");
    startScreen.classList.add("active");
}

// Event Listeners
startBtn.addEventListener("click", startQuiz);
restartBtn.addEventListener("click", restartQuiz);
answerButtons.forEach(function(button) {
    button.addEventListener("click", selectAnswer);
});

What does this code do?

The restartQuiz function hides the results screen and brings back the start screen so the player can go again.

The event listeners are what connect your HTML buttons to your JavaScript functions. addEventListener("click", ...) tells the browser to run the specified function whenever that button is clicked. Without these, clicking the buttons would do nothing.

  • Save script.js.
  • Switch to your browser. Click the **Start Quiz** button.
  • You should see the start screen disappear and the first question slide in with four answer buttons.
  • Click any answer. The correct answer flashes green, wrong answers flash red, and after a brief pause the next question slides in.

Clicking Start Quiz does nothing?

  • Open the browser console and look for red errors. A typo in any function name (like showquestion instead of showQuestion) will prevent the quiz from working.
  • Make sure your event listeners are at the very bottom of script.js, below all function definitions.
  • Check that the ID strings in your querySelector calls match your HTML exactly (including the # prefix for IDs and . prefix for classes).

Help me debug why my quiz Start button doesn't work.

✔️ Awesome, I've got everything!

Great. Double check you've saved script.js and your quiz is responding to clicks in the browser.

ⓧ I'd like to double check the full code

Here is the complete script.js file. Compare yours against it:

// Quiz Data
const quizData = [
    {
        question: "What does HTML stand for?",
        answers: ["Hyper Text Markup Language", "High Tech Modern Language", "Home Tool Markup Language", "Hyperlinks and Text Markup Language"],
        correct: 0
    },
    {
        question: "Which CSS property is used to change the text color?",
        answers: ["font-color", "text-color", "color", "foreground-color"],
        correct: 2
    },
    {
        question: "Which symbol is used for single-line comments in JavaScript?",
        answers: ["/* */", "//", "#", "--"],
        correct: 1
    },
    {
        question: "What does CSS stand for?",
        answers: ["Creative Style Sheets", "Cascading Style Sheets", "Computer Style Sheets", "Colorful Style Sheets"],
        correct: 1
    },
    {
        question: "Which HTML tag is used to create a hyperlink?",
        answers: ["<link>", "<href>", "<a>", "<url>"],
        correct: 2
    }
];

// State Variables
let currentQuestion = 0;
let score = 0;

// DOM Elements
const startScreen = document.querySelector("#start-screen");
const questionScreen = document.querySelector("#question-screen");
const resultsScreen = document.querySelector("#results-screen");
const startBtn = document.querySelector("#start-btn");
const questionText = document.querySelector("#question-text");
const answerButtons = document.querySelectorAll(".btn-answer");
const progressFill = document.querySelector("#progress-fill");
const questionCard = document.querySelector("#question-card");
const scoreText = document.querySelector("#score-text");
const restartBtn = document.querySelector("#restart-btn");

// Start Quiz
function startQuiz() {
    currentQuestion = 0;
    score = 0;
    startScreen.classList.remove("active");
    questionScreen.classList.add("active");
    showQuestion();
}

// Display Current Question
function showQuestion() {
    const data = quizData[currentQuestion];
    questionText.textContent = data.question;

    answerButtons.forEach(function(button, index) {
        button.textContent = data.answers[index];
        button.classList.remove("correct", "wrong");
        button.disabled = false;
    });

    // Update progress bar
    const progress = (currentQuestion / quizData.length) * 100;
    progressFill.style.width = progress + "%";

    // Trigger slide-in animation
    questionCard.classList.remove("slide-out");
    questionCard.style.animation = "none";
    questionCard.offsetHeight; // Force reflow to restart animation
    questionCard.style.animation = "";
}

// Handle Answer Selection
function selectAnswer(event) {
    const selectedIndex = Number(event.target.dataset.index);
    const correctIndex = quizData[currentQuestion].correct;

    // Disable all buttons
    answerButtons.forEach(function(button) {
        button.disabled = true;
    });

    // Show correct/wrong feedback
    if (selectedIndex === correctIndex) {
        event.target.classList.add("correct");
        score++;
    } else {
        event.target.classList.add("wrong");
        answerButtons[correctIndex].classList.add("correct");
    }

    // Advance after delay
    setTimeout(function() {
        currentQuestion++;
        if (currentQuestion < quizData.length) {
            questionCard.classList.add("slide-out");
            setTimeout(function() {
                showQuestion();
            }, 300);
        } else {
            showResults();
        }
    }, 1000);
}

// Show Results
function showResults() {
    questionScreen.classList.remove("active");
    resultsScreen.classList.add("active");
    scoreText.textContent = "You scored " + score + " out of " + quizData.length + "!";
    progressFill.style.width = "100%";
}

// Restart Quiz
function restartQuiz() {
    resultsScreen.classList.remove("active");
    startScreen.classList.add("active");
}

// Event Listeners
startBtn.addEventListener("click", startQuiz);
restartBtn.addEventListener("click", restartQuiz);
answerButtons.forEach(function(button) {
    button.addEventListener("click", selectAnswer);
});

Your quiz is fully playable. Next, you'll test the full flow end-to-end and add some polishing touches to make the experience feel smooth.

Test and Polish Your Quiz

Your quiz has all three layers in place: HTML for structure, CSS for style and animation, and JavaScript for logic and interactivity.

In this final step, you'll play through the quiz end-to-end to confirm everything works together. You'll verify that feedback, animations, and scoring all behave correctly before calling your project complete.

In this step, get ready to:
  • Play through the entire quiz and verify correct/incorrect feedback.
  • Confirm that timing delays and animations create a smooth experience.
Play through the quiz in your browser

The best way to confirm your code works is to use the quiz exactly like a real player would. You'll click through every question and watch for specific behaviors at each step.

  • Switch back to your browser where Live Server is running.
  • Click Start Quiz to begin.
  • Answer the first question correctly by selecting Hyper Text Markup Language.
  • Watch for the button to flash green and scale up slightly.
  • Answer the second question incorrectly by selecting any wrong option.
  • Watch for your selected button to turn red, and the correct answer (color) to highlight green.
  • Continue through all 5 questions, mixing correct and incorrect answers.
  • Verify the results screen displays your final score (e.g. "You scored 3 out of 5!").
  • Click Play Again and confirm you return to the start screen.

What should I see?

Here's the full sequence of behaviors to confirm at each stage:

  • Correct answers flash green and scale up. Wrong answers flash red and scale down.
  • After answering, all four buttons become unclickable (the cursor changes to a "not allowed" icon).
  • After about 1 second, the question card slides out to the left and a new one slides in from the right.
  • The progress bar fills incrementally after each question.

Quiz not behaving as expected?

  • If clicking an answer does nothing, open DevTools (Cmd+Option+I on macOS, Ctrl+Shift+I on Windows) and check the Console tab for red error messages.
  • If the progress bar doesn't move, check that progressFill in script.js uses the selector #progress-fill which must match the id in your HTML.
  • If the slide animation doesn't play, make sure style.css is saved and contains both the slideIn and slideOut keyframes.

Help me debug my quiz game. Something isn't working right when I click answers.

Verify the finishing touches

Your quiz already handles three common UX problems that trip up beginner web projects. Let's confirm each one is working and understand why it matters.

  • Start a new quiz round by clicking Play Again, then Start Quiz.
  • Click an answer, then immediately try to click a different answer button.
  • Confirm that the second click does nothing. The buttons should be disabled.
  • Watch the timing after you select an answer. You should see the color feedback hold for about 1 second before the card slides away.
  • Watch the slide transition itself. The current card should slide out to the left before the new question slides in from the right.

How do these finishing touches work?

Three patterns in your selectAnswer function create this polished experience:

  • button.disabled = true on every button prevents double-clicks. Once you select an answer, all four buttons become unresponsive.
  • setTimeout(function() { ... }, 1000) creates a 1-second pause so the learner can see the green/red feedback before the quiz advances.
  • A nested setTimeout(function() { showQuestion(); }, 300) waits 300 milliseconds for the slide-out animation to finish before loading the next question with a fresh slide-in.

Why disable buttons instead of removing event listeners?

Setting disabled = true on a button does two things at once. It stops the click event from firing, and it triggers the CSS :disabled styles (the reduced opacity and "not allowed" cursor).

Removing and re-adding event listeners would accomplish the same logic, but you'd lose the built-in visual feedback for free.

Buttons still clickable after answering?

  • Check that the answerButtons.forEach loop at the top of selectAnswer sets button.disabled = true on every button, not just the one clicked.
  • Make sure showQuestion resets button.disabled = false for the next question. Without this, buttons stay locked permanently.

Why are my quiz buttons still clickable after I select an answer?

Save all three files (index.html, style.css, script.js) and play through the quiz one more time from start to finish to confirm the complete experience.

✔️ Awesome, I've got everything!

Great. Double check that all three files are saved and your quiz runs smoothly from start to results.

ⓧ I'd like to double check the full code

Here's the complete code for all three files. Compare yours against these:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quiz Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="quiz-container">
        <!-- Start Screen -->
        <div id="start-screen" class="screen active">
            <h1 class="title">Quiz Game</h1>
            <p class="subtitle">Test your knowledge!</p>
            <button id="start-btn" class="btn btn-start">Start Quiz</button>
        </div>

        <!-- Question Screen -->
        <div id="question-screen" class="screen">
            <div class="progress-bar">
                <div id="progress-fill" class="progress-fill"></div>
            </div>
            <div id="question-card" class="question-card">
                <h2 id="question-text" class="question-text"></h2>
                <div class="answers-grid">
                    <button class="btn btn-answer" data-index="0"></button>
                    <button class="btn btn-answer" data-index="1"></button>
                    <button class="btn btn-answer" data-index="2"></button>
                    <button class="btn btn-answer" data-index="3"></button>
                </div>
            </div>
        </div>

        <!-- Results Screen -->
        <div id="results-screen" class="screen">
            <h2 class="results-title">Quiz Complete!</h2>
            <p id="score-text" class="score-text"></p>
            <button id="restart-btn" class="btn btn-start">Play Again</button>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #1a1a2e;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

.quiz-container {
    background-color: #16213e;
    border-radius: 20px;
    padding: 40px;
    width: 500px;
    max-width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

.screen {
    display: none;
    text-align: center;
}

.screen.active {
    display: block;
}

/* Start Screen */
.title {
    color: #e94560;
    font-size: 2.5rem;
    margin-bottom: 10px;
    animation: fadeInDown 0.6s ease;
}

.subtitle {
    color: #a8a8b3;
    font-size: 1.1rem;
    margin-bottom: 30px;
}

@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Buttons */
.btn {
    border: none;
    border-radius: 12px;
    padding: 15px 30px;
    font-size: 1rem;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.3s ease;
}

.btn:hover {
    transform: scale(1.05);
}

.btn-start {
    background-color: #e94560;
    color: white;
    font-size: 1.2rem;
    padding: 18px 40px;
}

.btn-start:hover {
    background-color: #d63851;
}

/* Progress Bar */
.progress-bar {
    background-color: #0f3460;
    border-radius: 10px;
    height: 10px;
    margin-bottom: 30px;
    overflow: hidden;
}

.progress-fill {
    background-color: #e94560;
    height: 100%;
    width: 0%;
    border-radius: 10px;
    transition: width 0.4s ease;
}

/* Question Card */
.question-card {
    animation: slideIn 0.4s ease;
}

.question-card.slide-out {
    animation: slideOut 0.3s ease forwards;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes slideOut {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(-30px);
    }
}

.question-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 25px;
    line-height: 1.4;
}

/* Answers Grid */
.answers-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.btn-answer {
    background-color: #0f3460;
    color: #ffffff;
    padding: 18px 15px;
    text-align: center;
}

.btn-answer:hover {
    background-color: #1a4a7a;
}

.btn-answer.correct {
    background-color: #27ae60;
    transform: scale(1.05);
}

.btn-answer.wrong {
    background-color: #e74c3c;
    transform: scale(0.95);
}

.btn-answer:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

.btn-answer:disabled:hover {
    transform: none;
}

/* Results Screen */
.results-title {
    color: #e94560;
    font-size: 2rem;
    margin-bottom: 20px;
    animation: fadeInDown 0.6s ease;
}

.score-text {
    color: #ffffff;
    font-size: 1.3rem;
    margin-bottom: 30px;
}
// Quiz Data
const quizData = [
    {
        question: "What does HTML stand for?",
        answers: ["Hyper Text Markup Language", "High Tech Modern Language", "Home Tool Markup Language", "Hyperlinks and Text Markup Language"],
        correct: 0
    },
    {
        question: "Which CSS property is used to change the text color?",
        answers: ["font-color", "text-color", "color", "foreground-color"],
        correct: 2
    },
    {
        question: "Which symbol is used for single-line comments in JavaScript?",
        answers: ["/* */", "//", "#", "--"],
        correct: 1
    },
    {
        question: "What does CSS stand for?",
        answers: ["Creative Style Sheets", "Cascading Style Sheets", "Computer Style Sheets", "Colorful Style Sheets"],
        correct: 1
    },
    {
        question: "Which HTML tag is used to create a hyperlink?",
        answers: ["<link>", "<href>", "<a>", "<url>"],
        correct: 2
    }
];

// State Variables
let currentQuestion = 0;
let score = 0;

// DOM Elements
const startScreen = document.querySelector("#start-screen");
const questionScreen = document.querySelector("#question-screen");
const resultsScreen = document.querySelector("#results-screen");
const startBtn = document.querySelector("#start-btn");
const questionText = document.querySelector("#question-text");
const answerButtons = document.querySelectorAll(".btn-answer");
const progressFill = document.querySelector("#progress-fill");
const questionCard = document.querySelector("#question-card");
const scoreText = document.querySelector("#score-text");
const restartBtn = document.querySelector("#restart-btn");

// Start Quiz
function startQuiz() {
    currentQuestion = 0;
    score = 0;
    startScreen.classList.remove("active");
    questionScreen.classList.add("active");
    showQuestion();
}

// Display Current Question
function showQuestion() {
    const data = quizData[currentQuestion];
    questionText.textContent = data.question;

    answerButtons.forEach(function(button, index) {
        button.textContent = data.answers[index];
        button.classList.remove("correct", "wrong");
        button.disabled = false;
    });

    // Update progress bar
    const progress = (currentQuestion / quizData.length) * 100;
    progressFill.style.width = progress + "%";

    // Trigger slide-in animation
    questionCard.classList.remove("slide-out");
    questionCard.style.animation = "none";
    questionCard.offsetHeight; // Force reflow to restart animation
    questionCard.style.animation = "";
}

// Handle Answer Selection
function selectAnswer(event) {
    const selectedIndex = Number(event.target.dataset.index);
    const correctIndex = quizData[currentQuestion].correct;

    // Disable all buttons
    answerButtons.forEach(function(button) {
        button.disabled = true;
    });

    // Show correct/wrong feedback
    if (selectedIndex === correctIndex) {
        event.target.classList.add("correct");
        score++;
    } else {
        event.target.classList.add("wrong");
        answerButtons[correctIndex].classList.add("correct");
    }

    // Advance after delay
    setTimeout(function() {
        currentQuestion++;
        if (currentQuestion < quizData.length) {
            questionCard.classList.add("slide-out");
            setTimeout(function() {
                showQuestion();
            }, 300);
        } else {
            showResults();
        }
    }, 1000);
}

// Show Results
function showResults() {
    questionScreen.classList.remove("active");
    resultsScreen.classList.add("active");
    scoreText.textContent = "You scored " + score + " out of " + quizData.length + "!";
    progressFill.style.width = "100%";
}

// Restart Quiz
function restartQuiz() {
    resultsScreen.classList.remove("active");
    startScreen.classList.add("active");
}

// Event Listeners
startBtn.addEventListener("click", startQuiz);
restartBtn.addEventListener("click", restartQuiz);
answerButtons.forEach(function(button) {
    button.addEventListener("click", selectAnswer);
});

Secret mission

Add a Countdown Timer

Your quiz works great, but there's no time pressure. Real quiz games keep you on your toes with a ticking clock. In this secret mission, you'll add a 15-second countdown timer that creates urgency and auto-advances when time runs out.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • The quiz-game folder on your Desktop containing index.html, style.css, and script.js.
  • The Live Server extension installed in VS Code.

Keep everything running

No action needed. Choose this if you're still actively building or want to keep experimenting with your quiz game.

  • Your quiz-game folder stays on your Desktop, ready to open anytime.
  • Live Server stays installed in VS Code for future projects.
  • To reopen the project, launch VS Code and use File > Open Folder to select the quiz-game folder.

Pause - I'll come back to this later

Stop Live Server to free up the port it uses. Your files stay intact for when you return.

  • In VS Code, click Go Live in the bottom status bar to stop the server (it toggles off).
  • Close the browser tab that Live Server opened.
  • Your quiz-game folder and all three files remain on your Desktop.

Delete - I don't want to use this again

Remove all project files and extensions you no longer need.

  • Stop Live Server by clicking Go Live in the VS Code status bar.
  • Close the browser tab that Live Server opened.
  • Delete the project folder by running this command in your terminal (macOS/Linux):
rm -rf ~/Desktop/quiz-game

On Windows, run this in PowerShell instead:

Remove-Item -Recurse -Force ~\Desktop\quiz-game
  • To uninstall Live Server, click the Extensions icon in the VS Code sidebar, find Live Server by Ritwick Dey, click the gear icon, and select Uninstall.

Nice Work!

Nice Work!

You just built an interactive quiz game from scratch using nothing but three files and a browser. That is the foundation of all web development.

You've learned how to:

  • Built a complete HTML document with semantic structure that organizes a multi-screen application.
  • Styled a modern UI with CSS Flexbox, transitions, and keyframe animations that give real-time visual feedback.
  • Wrote JavaScript that manipulates the DOM, handles events, and manages application state across multiple screens.
  • Added a countdown timer with setInterval and clearInterval for real-time interactivity.

Ready to quiz yourself?