Build an Interactive Quiz App
Build a browser-based quiz app using core JavaScript fundamentals.
Introduction
30 Second Summary
Quizzes are everywhere. From trivia nights to language-learning apps, they test your knowledge and keep you engaged through instant feedback.
In this project, you will build an interactive quiz app using HTML, CSS, and JavaScript. You will create a fully functional browser app that presents questions, checks answers, tracks your score, and displays results.
What You'll Build
A multiple-choice quiz app that runs entirely in the browser, built with vanilla JavaScript, HTML, and CSS.
By the end of this project, you'll have:
- A working HTML page with a quiz card layout, answer buttons, and a results screen.
- A CSS stylesheet with modern styling and visual feedback states for correct and wrong answers.
- A JavaScript file containing all quiz logic including dynamic DOM manipulation, event listeners, score tracking, and conditional answer checking.
- Secret Mission: Add a countdown timer that gives the player 15 seconds per question.
Are there any prerequisites?
None. This guide includes full setup instructions for every tool you need. You do not need any prior coding experience to complete this project.
Before We Start
You are about to build a fully interactive quiz app that runs in the browser. The app presents multiple-choice questions, gives instant visual feedback on your answer, and tracks your score.
To build this, you need three things: a code editor to write your files, a way to see your changes instantly in the browser, and a project folder to keep everything organised. This step gets all of that ready.
In this step, get ready to:
- Install Visual Studio Code as your code editor.
- Add the Live Server extension for instant browser previews.
- Create your project folder with three starter files.
Install Visual Studio Code
Visual Studio Code is a free code editor that works on macOS, Windows, and Linux. It is the most popular editor for web development and supports extensions that add extra features.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Visual Studio Code and press Enter.
✔️ VS Code opens
You are ready to go. Skip ahead to the next substep.
ⓧ I don't have VS Code yet
- Open your web browser and go to https://code.visualstudio.com.
- Click the download button for your operating system.
- Run the installer and follow the prompts to complete the installation.
- Once installed, open VS Code using the search method above.
What does the installer do?
The installer adds code to your PATH so you can open folders from the terminal later. It also creates a shortcut you can find through your system search.
Install the Live Server extension
Live Server is a VS Code extension that launches a local development server. Every time you save a file, it automatically refreshes your browser so you see changes instantly.
- In VS Code, open the Extensions panel by pressing Cmd+Shift+X (macOS) or Ctrl+Shift+X (Windows).
- Type Live Server into the search field at the top of the panel.
- Find the result by Ritwick Dey (it has 79M+ installs).
- Click Install.
Why Live Server?
Without Live Server, you would need to manually refresh the browser every time you change a file. Live Server watches your project folder and pushes updates to the browser automatically.
This keeps your feedback loop fast so you can see the effect of every code change within seconds.
Don't see Live Server in the results?
Make sure you are searching in the Extensions panel (the icon looks like four squares in the left sidebar), not in the file search bar. The extension's full name is Live Server and the publisher is Ritwick Dey.
Help me find and install the Live Server extension in VS Code.
Create your project folder and files
Your quiz app needs three files: one for the page structure, one for styling, and one for the interactive logic. You will create all three inside a dedicated project folder on your Desktop.
- In VS Code, click File in the top menu bar.
- Click Open Folder.
- Navigate to your Desktop in the file dialog.
- Click New Folder (macOS) or right-click and select New then Folder (Windows).
- Name the folder js-quiz-app.
- Select the js-quiz-app folder and click Open (macOS) or Select Folder (Windows).
VS Code now shows the empty js-quiz-app folder in the Explorer sidebar on the left.
- Hover over the JS-QUIZ-APP heading in the Explorer sidebar to reveal the action icons.
- Click the New File icon (it looks like a page with a 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.
You should now see all three files listed in the Explorer sidebar: index.html, style.css, and script.js.
Don't see the Explorer sidebar?
Press Cmd+Shift+E (macOS) or Ctrl+Shift+E (Windows) to toggle the Explorer panel. If you still see a welcome tab instead of your files, make sure you opened the js-quiz-app folder (not just a single file).
Help me get the VS Code Explorer sidebar showing my project files.
Your workspace is ready. Next up, you will build the HTML structure that gives your quiz app its skeleton.
Build the HTML Structure
Your development environment is set up and ready to go. Now it's time to build the skeleton of your quiz app.
Every interactive web app starts with HTML that defines structure and placeholders. JavaScript will bring these placeholders to life later with real quiz data and behavior.
In this step, get ready to:
- Build the quiz page skeleton with a question area, answer buttons container, and results section.
- Launch Live Server to preview your page in the browser.
Create the quiz page skeleton
Your quiz app needs two views: the active quiz (showing a question and answer buttons) and a results screen (showing the final score). You'll build both inside a single HTML file, and JavaScript will toggle between them later.
- In VS Code, click on index.html in the Explorer sidebar to open it.
- 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>JavaScript Quiz App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="quiz-container">
<div class="quiz">
<h2 id="question">Question text goes here</h2>
<div id="options"></div>
<button id="next-btn">Next</button>
</div>
<div class="results" id="results">
<h2>Quiz Complete!</h2>
<p id="score-text"></p>
<button id="restart-btn">Restart Quiz</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
What does this code do?
This HTML sets up two separate views inside a single quiz-container wrapper:
- The .quiz div holds the active quiz: an h2 for the question text, an empty div#options where JavaScript will inject answer buttons, and a "Next" button to advance.
- The .results div is the end screen. It stays hidden until the quiz finishes, then displays the player's score and a restart button.
- The <link> in the head connects your stylesheet, and the <script> at the bottom of the body loads your JavaScript after the HTML is ready.
- Save index.html by pressing Cmd+S (macOS) or Ctrl+S (Windows).
- Right-click index.html in the VS Code Explorer sidebar.
- Select Open with Live Server.
Your default browser opens and displays the quiz layout. You should see "Question text goes here" as a heading, a "Next" button, and "Quiz Complete!" text below it.
Why does everything show at once?
Right now both the quiz view and the results view are visible because you haven't added CSS or JavaScript yet. In later steps, CSS will hide the results section by default, and JavaScript will toggle between the two views.
Page is blank or shows raw HTML?
- Make sure you saved the file. Unsaved files in VS Code show a white dot on the tab.
- Check that you right-clicked index.html specifically, not one of the other files. Live Server needs an HTML file to launch.
- Verify your opening <!DOCTYPE html> tag is on the very first line with no blank lines above it.
Still not working? Help me troubleshoot why my index.html isn't rendering in Live Server.
✔️ Awesome, I've got everything!
Great. Double check you've saved your file, then you're ready to move on.
ⓧ I'd like to double check the full code
Here's the complete index.html file. Compare yours against it line by line.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Quiz App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="quiz-container">
<div class="quiz">
<h2 id="question">Question text goes here</h2>
<div id="options"></div>
<button id="next-btn">Next</button>
</div>
<div class="results" id="results">
<h2>Quiz Complete!</h2>
<p id="score-text"></p>
<button id="restart-btn">Restart Quiz</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Your HTML skeleton is in place. Next up, you'll add CSS to turn this raw structure into a polished, dark-themed quiz card.
Style the Quiz with CSS
Your HTML skeleton is in place, but right now it looks like a bare, unstyled document from the 1990s. CSS transforms that raw structure into a polished, modern interface.
In this step, you will style the quiz card with a dark colour scheme, position it in the centre of the page, and create visual feedback classes that JavaScript will use later to show correct and wrong answers.
In this step, get ready to:
- Style the page layout and quiz card appearance.
- Add visual feedback states for correct, wrong, and disabled answers.
Style the quiz card
The first thing to style is the page itself and the card that holds your quiz. This gives the app its overall look and feel before you worry about individual elements inside.
- Open style.css in VS Code by clicking on it in the Explorer sidebar.
- Add the page layout and quiz card styles by pasting this code:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #1a1a2e;
}
.quiz-container {
background-color: #16213e;
border-radius: 12px;
padding: 32px;
width: 100%;
max-width: 500px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
What does this code do?
The * selector resets all default browser spacing so every element starts from zero. This prevents inconsistent margins and padding across different browsers.
The body uses flexbox to centre everything both horizontally and vertically. The dark #1a1a2e background gives the page a modern look.
The .quiz-container creates a card with rounded corners and a subtle shadow. The max-width: 500px keeps the card from stretching too wide on large screens.
- Save style.css by pressing Cmd+S (macOS) or Ctrl+S (Windows).
- Check your browser. You should see the entire page turn dark navy, with a slightly lighter blue card centred in the middle.
Still seeing a white page?
- Make sure you saved style.css. Live Server only refreshes after a save.
- Confirm that your index.html has <link rel="stylesheet" href="style.css"> in the <head> section.
- Check that style.css is in the same folder as index.html. If it is in a subfolder, the link path will not match.
Why is my CSS not applying to the page?
Now let's style the question text and the answer buttons that will appear inside the card.
- Add the question and button styles below your existing code in style.css:
.quiz h2 {
color: #e0e0e0;
font-size: 1.3rem;
margin-bottom: 20px;
line-height: 1.4;
}
#options {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
}
#options button {
padding: 14px 20px;
border: 2px solid #0f3460;
border-radius: 8px;
background-color: #0f3460;
color: #e0e0e0;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s, border-color 0.3s;
text-align: left;
}
#options button:hover {
background-color: #1a4a7a;
border-color: #1a4a7a;
}
What does this code do?
The .quiz h2 styles the question text in light gray with comfortable line spacing so longer questions are easy to read.
The #options container uses flexbox in a column direction with a gap of 12px to space out answer buttons evenly without needing margins on each one.
Each button gets a dark blue background with a smooth transition so colour changes animate instead of snapping. The :hover state lightens the button when the cursor passes over it.
- Save style.css.
- Check your browser. The placeholder question text now appears in light gray inside the card. The Next button is still a default browser button at this point.
Question text not changing colour?
- Make sure your selector is .quiz h2 (with a space). Without the space, CSS looks for an element with both classes instead of an h2 inside .quiz.
- Check that the new code is below the closing } of the previous selector. Placing it inside another rule will break both.
Why is my CSS selector not targeting the right element?
Add feedback states
When a player clicks an answer, the app needs to show whether they got it right or wrong. CSS classes handle this visual feedback. JavaScript will add these classes to buttons later.
- Add the feedback classes below your existing code in style.css:
#options button.correct {
background-color: #2ecc71;
border-color: #2ecc71;
color: #fff;
}
#options button.wrong {
background-color: #e74c3c;
border-color: #e74c3c;
color: #fff;
}
#options button.disabled {
pointer-events: none;
opacity: 0.8;
}
What does this code do?
The .correct class turns a button green to indicate the right answer. The .wrong class turns it red to show an incorrect choice.
The .disabled class uses pointer-events: none to block all click interactions on a button. Once an answer is selected, JavaScript will add this class to every button so the player cannot change their answer.
- Save style.css.
- You will not see these feedback classes in action yet. JavaScript adds them to buttons at runtime, which you will build in the next step.
Finally, let's style the Next button, the results screen, and the Restart button.
- Add the navigation and results styles below your existing code in style.css:
#next-btn {
display: none;
padding: 12px 24px;
background-color: #e94560;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
#next-btn:hover {
background-color: #c0392b;
}
.results {
display: none;
text-align: center;
}
.results h2 {
color: #e0e0e0;
margin-bottom: 16px;
}
.results p {
color: #b0b0b0;
font-size: 1.2rem;
margin-bottom: 24px;
}
#restart-btn {
padding: 12px 24px;
background-color: #e94560;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
#restart-btn:hover {
background-color: #c0392b;
}
What does this code do?
The #next-btn starts with display: none so it is invisible until JavaScript reveals it after the player picks an answer.
The .results section is also hidden by default. JavaScript will swap it into view when all questions are answered. The #restart-btn shares the same pink accent colour as the Next button to keep the design consistent.
- Save style.css.
- Check your browser. The Next button has disappeared and the results section is hidden. Your page now shows just the dark card with the question placeholder text inside it.
Next button still visible?
- Make sure your selector is #next-btn (with the hash symbol). Without the #, CSS does not recognise it as an ID selector.
- Verify that display: none is the first property inside the #next-btn rule. A typo or missing semicolon on the line above can break it.
Why is my button not hiding with display none?
✔️ Awesome, I've got everything!
Great. Double check you have saved style.css and your browser shows the dark centered card.
ⓧ I'd like to double check the full code
Here is the complete style.css file. Make sure yours matches exactly.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #1a1a2e;
}
.quiz-container {
background-color: #16213e;
border-radius: 12px;
padding: 32px;
width: 100%;
max-width: 500px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.quiz h2 {
color: #e0e0e0;
font-size: 1.3rem;
margin-bottom: 20px;
line-height: 1.4;
}
#options {
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 20px;
}
#options button {
padding: 14px 20px;
border: 2px solid #0f3460;
border-radius: 8px;
background-color: #0f3460;
color: #e0e0e0;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s, border-color 0.3s;
text-align: left;
}
#options button:hover {
background-color: #1a4a7a;
border-color: #1a4a7a;
}
#options button.correct {
background-color: #2ecc71;
border-color: #2ecc71;
color: #fff;
}
#options button.wrong {
background-color: #e74c3c;
border-color: #e74c3c;
color: #fff;
}
#options button.disabled {
pointer-events: none;
opacity: 0.8;
}
#next-btn {
display: none;
padding: 12px 24px;
background-color: #e94560;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
#next-btn:hover {
background-color: #c0392b;
}
.results {
display: none;
text-align: center;
}
.results h2 {
color: #e0e0e0;
margin-bottom: 16px;
}
.results p {
color: #b0b0b0;
font-size: 1.2rem;
margin-bottom: 24px;
}
#restart-btn {
padding: 12px 24px;
background-color: #e94560;
color: #fff;
border: none;
border-radius: 8px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
#restart-btn:hover {
background-color: #c0392b;
}
Your quiz card looks polished and ready to go. Next up, you will bring it to life with JavaScript by loading questions, handling clicks, and tracking the player's score.
Add JavaScript Quiz Logic
Your quiz looks great, but clicking those buttons does nothing yet. The HTML and CSS created the visual structure. Now you need JavaScript to bring it to life.
In this step, you will write all the quiz logic: storing questions as data, reading from the HTML page, and responding to user clicks with instant visual feedback.
In this step, get ready to:
- Define quiz questions as structured data in an array of objects.
- Connect JavaScript to the HTML elements on the page.
- Write functions to handle quiz interactions, scoring, and navigation.
Define the quiz questions
Every quiz needs questions, answer choices, and a way to know which answer is correct. In JavaScript, you can store all of this in an array of objects. Each object holds one question's data.
- Open script.js in VS Code (it should be empty).
- Add the quiz data array by pasting in this code:
const quizData = [
{
question: "Which keyword is used to declare a variable that cannot be reassigned?",
options: ["var", "let", "const", "static"],
correct: 2
},
{
question: "What does DOM stand for?",
options: ["Document Object Model", "Data Object Module", "Digital Output Map", "Document Order Method"],
correct: 0
},
{
question: "Which method selects an element by CSS selector?",
options: ["getElementById()", "querySelector()", "getElement()", "findSelector()"],
correct: 1
},
{
question: "What is the output of typeof []?",
options: ["array", "object", "list", "undefined"],
correct: 1
},
{
question: "Which array method adds an element to the end of an array?",
options: ["shift()", "unshift()", "pop()", "push()"],
correct: 3
}
];
What does this code do?
This creates a const variable called quizData that holds an array of 5 objects. Each object represents one question.
- question is the question text displayed to the player.
- options is an array of 4 possible answer strings.
- correct is the index (starting at 0) of the right answer in the options array.
You won't see a change in the browser yet. The functions you write next will use this data to display questions.
Seeing a red error in the browser console?
If you save now and check your browser's developer console, you might see an error. That is expected because the rest of the code (which uses quizData) does not exist yet. It will go away once you finish this step.
If nothing happens at all, check that your array brackets [] and curly braces {} are correctly matched. Every opening bracket needs a closing one.
Help me fix a syntax error in my quizData array
Select DOM elements and track state
Your JavaScript needs to reach into the HTML page and grab references to the elements it will update. It also needs variables to remember which question the player is on and their current score.
- In script.js, add this code below the quizData array:
// Grab references to HTML elements the quiz will update
const questionEl = document.querySelector("#question");
const optionsEl = document.querySelector("#options");
const nextBtn = document.querySelector("#next-btn");
const resultsEl = document.querySelector("#results");
const scoreTextEl = document.querySelector("#score-text");
const restartBtn = document.querySelector("#restart-btn");
const quizEl = document.querySelector(".quiz");
// Track which question we're on and the player's score
let currentQuestion = 0;
let score = 0;
What does this code do?
document.querySelector() finds an HTML element using the same selectors you use in CSS. The # targets elements by their id attribute, and . targets elements by their class.
The two let variables store the quiz state. currentQuestion starts at 0 (the first item in the array). score starts at 0 and increases with each correct answer. We use let instead of const because these values will change as the quiz progresses.
Still no visible change in the browser. These references give your functions a way to reach into the page and update content.
Build the quiz functions
Now for the exciting part. You will write five functions that handle every part of the quiz flow: displaying a question, checking the answer, moving to the next question, showing results, and restarting.
- In script.js, add this code below the state variables:
function loadQuestion() {
// Get the current question object from the array
const data = quizData[currentQuestion];
questionEl.textContent = data.question;
optionsEl.innerHTML = "";
nextBtn.style.display = "none";
// Create a button for each answer option
data.options.forEach(function (option, index) {
const button = document.createElement("button");
button.textContent = option;
button.addEventListener("click", function () {
selectAnswer(index);
});
optionsEl.appendChild(button);
});
}
function selectAnswer(selectedIndex) {
// Check the answer and apply visual feedback
const data = quizData[currentQuestion];
const buttons = optionsEl.querySelectorAll("button");
// Disable all buttons and highlight the correct answer
buttons.forEach(function (button, index) {
button.classList.add("disabled");
if (index === data.correct) {
button.classList.add("correct");
}
});
// Update score or mark wrong answer
if (selectedIndex === data.correct) {
score++;
} else if (selectedIndex >= 0) {
buttons[selectedIndex].classList.add("wrong");
}
nextBtn.style.display = "block";
}
function nextQuestion() {
// Move to next question or show results if quiz is done
currentQuestion++;
if (currentQuestion < quizData.length) {
loadQuestion();
} else {
showResults();
}
}
function showResults() {
// Hide quiz view and display final score
quizEl.style.display = "none";
resultsEl.style.display = "block";
scoreTextEl.textContent = "You scored " + score + " out of " + quizData.length + "!";
}
function restartQuiz() {
// Reset state and start over
currentQuestion = 0;
score = 0;
quizEl.style.display = "block";
resultsEl.style.display = "none";
loadQuestion();
}
// Wire up button clicks and start the quiz
nextBtn.addEventListener("click", nextQuestion);
restartBtn.addEventListener("click", restartQuiz);
loadQuestion();
What does this code do?
- loadQuestion() reads the current question from quizData, sets the question text, clears old answer buttons, and creates new buttons with click listeners.
- selectAnswer() disables all buttons, highlights the correct answer green, marks the wrong pick red, updates the score, and reveals the Next button.
- nextQuestion() advances the index. If there are more questions, it loads the next one. Otherwise it calls showResults().
- showResults() hides the quiz view and displays the final score.
- restartQuiz() resets the score and question index back to zero, then reloads the first question.
The last three lines wire the Next and Restart buttons to their functions, then call loadQuestion() to display the first question as soon as the page loads.
- Save script.js.
- Switch to your browser. Live Server should auto-refresh the page.
- You should see the first question displayed with four clickable answer buttons.
- Click any answer. The correct answer highlights green, and if you picked wrong, your choice turns red. All buttons become unclickable.
- Click Next to advance through all 5 questions.
- After the final question, the results screen appears with your score and a Restart Quiz button that resets everything.
Quiz not loading or buttons not working?
- Open your browser's developer console (press F12 then click the Console tab). Red error messages tell you what went wrong and which line to check.
- Make sure your script.js file is saved. Unsaved changes will not appear in the browser.
- Check that the element IDs in your querySelector calls match your HTML exactly. For example, #next-btn must match id="next-btn" in index.html.
Help me debug why my quiz app is not loading questions
✔️ Awesome, I've got everything!
Great. Double check you have saved script.js and that the full quiz flow works from first question through the results screen.
ⓧ I'd like to double check the full code
Here is the complete script.js file. Compare yours against it line by line.
const quizData = [
{
question: "Which keyword is used to declare a variable that cannot be reassigned?",
options: ["var", "let", "const", "static"],
correct: 2
},
{
question: "What does DOM stand for?",
options: ["Document Object Model", "Data Object Module", "Digital Output Map", "Document Order Method"],
correct: 0
},
{
question: "Which method selects an element by CSS selector?",
options: ["getElementById()", "querySelector()", "getElement()", "findSelector()"],
correct: 1
},
{
question: "What is the output of typeof []?",
options: ["array", "object", "list", "undefined"],
correct: 1
},
{
question: "Which array method adds an element to the end of an array?",
options: ["shift()", "unshift()", "pop()", "push()"],
correct: 3
}
];
const questionEl = document.querySelector("#question");
const optionsEl = document.querySelector("#options");
const nextBtn = document.querySelector("#next-btn");
const resultsEl = document.querySelector("#results");
const scoreTextEl = document.querySelector("#score-text");
const restartBtn = document.querySelector("#restart-btn");
const quizEl = document.querySelector(".quiz");
let currentQuestion = 0;
let score = 0;
function loadQuestion() {
const data = quizData[currentQuestion];
questionEl.textContent = data.question;
optionsEl.innerHTML = "";
nextBtn.style.display = "none";
data.options.forEach(function (option, index) {
const button = document.createElement("button");
button.textContent = option;
button.addEventListener("click", function () {
selectAnswer(index);
});
optionsEl.appendChild(button);
});
}
function selectAnswer(selectedIndex) {
const data = quizData[currentQuestion];
const buttons = optionsEl.querySelectorAll("button");
buttons.forEach(function (button, index) {
button.classList.add("disabled");
if (index === data.correct) {
button.classList.add("correct");
}
});
if (selectedIndex === data.correct) {
score++;
} else if (selectedIndex >= 0) {
buttons[selectedIndex].classList.add("wrong");
}
nextBtn.style.display = "block";
}
function nextQuestion() {
currentQuestion++;
if (currentQuestion < quizData.length) {
loadQuestion();
} else {
showResults();
}
}
function showResults() {
quizEl.style.display = "none";
resultsEl.style.display = "block";
scoreTextEl.textContent = "You scored " + score + " out of " + quizData.length + "!";
}
function restartQuiz() {
currentQuestion = 0;
score = 0;
quizEl.style.display = "block";
resultsEl.style.display = "none";
loadQuestion();
}
nextBtn.addEventListener("click", nextQuestion);
restartBtn.addEventListener("click", restartQuiz);
loadQuestion();
Secret mission
Add a Countdown Timer
Your quiz works, but there is no pressure. What if each question had a ticking clock? In this secret mission, you will add a 15-second countdown timer that forces the player to think fast or lose the point.
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 js-quiz-app project folder on your Desktop.
- The Live Server extension in VS Code.
- Visual Studio Code application.
Keep everything running
No action needed. Choose this if you are still actively building or plan to extend the quiz app with more features.
- Your js-quiz-app folder stays on your Desktop, ready to open any time.
- Live Server stays installed in VS Code for future projects.
- VS Code stays installed on your machine for any development work.
Pause - I'll come back to this later
Stop the Live Server to free up the port it uses. Your files stay intact for when you return.
- In VS Code, click the Port: 5500 indicator in the bottom status bar to stop Live Server.
- Close VS Code. Your project files remain on your Desktop.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow the steps below for each resource you want to delete.
- Stop Live Server by clicking the Port: 5500 indicator in the VS Code status bar.
- Delete the project folder. On macOS/Linux, open Terminal and run the command below. On Windows, open PowerShell and run the Windows command below.
rm -rf ~/Desktop/js-quiz-app
Remove-Item -Recurse -Force "$HOME\Desktop\js-quiz-app"
- Uninstall the Live Server extension. In VS Code, press Ctrl+Shift+X to open the Extensions panel. Find Live Server in your installed list and click Uninstall.
- Uninstall VS Code. On macOS, drag the Visual Studio Code app from your Applications folder to the Trash. On Windows, open Settings, select Apps, find Microsoft Visual Studio Code, and click Uninstall.
Nice Work!
Nice Work!
Nice work! You just built a fully interactive quiz app from scratch using only HTML, CSS, and vanilla JavaScript.
You've learned how to:
- Store structured quiz data in arrays of objects and use that data to drive an entire application.
- Dynamically create and manipulate DOM elements using createElement, querySelector, textContent, and classList to build interactive UI from JavaScript.
- Handle user interactions with event listeners and manage application state (current question index, score) across multiple function calls.
- Secret Mission: Implemented a real-time countdown timer using setInterval and clearInterval to add time pressure to each question.
Ready to quiz yourself?