Build a Web Quiz App

Build a Web Quiz App

Level Up Your Skills: Build a Web Quiz App with Basic JS, HTML & CSS

Learning HTML, CSS, and JavaScript is exciting, but what's even better? Putting them to work with a fun project! This article is your perfect launchpad. We will guide you step-by-step through building an interactive quiz application using JavaScript, HTML, and CSS.

No prior experience building web apps is necessary, as long as you have a basic understanding of HTML tags, applying CSS styles, and using simple JavaScript functions. Learning by doing is one of the most effective ways to master new skills. This quiz app will give you hands-on experience that will solidify your understanding of HTML, CSS and JavaScript concepts in practical and rewarding way.

Throughout this article, we'll break down the process into easy-to-follow chunks. You will learn how to:

  • Structure your HTML document to hold the quiz content.

  • Style the quiz using CSS to make it visually appealing.

  • Add interactivity with JavaScript to handle user input, score calculation, and displaying results.

Throughout this tutorial, we'll provide code snippets and clear explanations to help you understand each step of the process. By the end of this journey, you'll have a functional quiz app you can be proud of, and you'll gain valuable experience putting your web development skills into practice! So, let's get started on building something awesome!

Setting Up Your Development Environment

In this step, we will start by setting up our development environment. We will be using Visual Studio Code (VS Code) as our code editor. It's a popular choice because of its user-friendly interface and extensive features.

For those who already have VS Code

Great! You're all set to jump to the next step. If you're new to VS Code, keep reading for quick installation instructions.

Installing VS Code (For New Users)

Getting started is easy! Head over to the official VS Code website and download the installer for your operating system. The installation process is straightforward, so just follow the on-screen instructions.

Once you have VS Code installed, open it up and let's create a new folder for our quiz app project. Here's a quick way to do it:

Go to File > New Folder (or press Ctrl + N). Give your project a memorable name, like "my-quiz-app".

That's it! Now you have a dedicated workspace for your quiz app in VS Code

1. HTML Code: Structuring the App

To get started, we'll first need to create a basic HTML file from the dedicated folder we created for our quiz app (named "my-quiz-app" or it could be any name you chose). Navigate to your quiz app folder (e.g., "my-quiz-app"). Right-click inside the folder, select "New File," and name it "index.html". This is a common naming convention for the main HTML file in a web project.

Now that you have your index.html file open in VS Code, let's paste the following code snippet:


<!DOCTYPE html>
<html>
    <head>
        <title>Quiz App</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div class="app"> 
            <h1>Simple Quiz</h1>
            <div class="quiz">
                <h2 id="question">Question goes here</h2>
                <div id="answer-buttons">
                    <button class="btn">Answer 1</button>
                    <button class="btn">Answer 2</button>
                    <button class="btn">Answer 3</button>
                    <button class="btn">Answer 4</button>
                </div>
                <button id="next-btn">Next</button>
            </div>
        </div>

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


    </body>
</html>

Here is an explanation for each element:

  1. <!DOCTYPE html>: This is the Document Type Declaration (DOCTYPE). It specifies that the document is written in HTML.

  2. <html>: This is the root element of the HTML document. It contains all other elements that define the content and structure of the webpage.

  3. <head>: This section contains meta information about the document that isn't directly displayed on the webpage itself.

    • <title>: This element defines the title displayed on the browser tab (here, "Quiz App").

    • <link rel="stylesheet" href="style.css">: This element links an external stylesheet file named "style.css" to the HTML document. This stylesheet will contain CSS styles to define the visual appearance of the quiz elements (e.g., fonts, colors, layout).

  4. <body>: This section contains the content that will be displayed on the webpage. Here, it holds the structure for your quiz app.

    • <div class="app">: This div element acts as a container for the entire quiz application. Assigning it a class of "app" allows you to target this specific section with CSS styles later.

    • <h1>Simple Quiz</h1>: This h1 element defines the main heading for your quiz application with the text "Simple Quiz".

    • <div class="quiz">: Another div element acts as a container for all the quiz-related elements like questions, answers, and buttons. Assigning it a class of "quiz" allows you to target this specific section with CSS styles later.

    • <h2 id="question">Question goes here</h2>: This h2 element defines the heading for each question within the quiz. It has an id attribute set to "question" which can be used in JavaScript to dynamically update the question text.

    • <div id="answer-buttons">: This div element acts as a container for all the answer buttons. It has an id attribute set to "answer-buttons" which can be used in JavaScript to interact with the answer buttons.

    • <button class="btn">Answer 1</button>: These button elements represent individual answer choices for each question. They all share a class of "btn" which can be used in CSS to style the buttons.

    • <button id="next-btn">Next</button>: This button element allows the user to navigate to the next question in the quiz. It has an id attribute set to "next-btn" which can be used in JavaScript to handle the "next question" functionality.

  5. <script src="script.js"></script>: This element references an external JavaScript file named "script.js". This script contain the logic for handling user interaction with the quiz, such as displaying questions, evaluating answers, and tracking progress.

Let's take the HTML foundation we've built and add some style with CSS! CSS allows us to control the visual presentation of our quiz application, making it not only functional but also engaging and informative for the user.

2. CSS Code: Styling the App

Now that you have the basic HTML structure in place, it's time to add some style! We'll use CSS (Cascading Style Sheets) to define the visual appearance of our quiz app elements, making it visually appealing and engaging.

We'll start by creating a CSS file from the same folder where your index.html resides (e.g., "my-quiz-app"), right-click again and choose "New File" and name it "style.css". This is another common naming convention for CSS files in web development.

Now that you have your style.css file open in VS Code, let's paste the following code snippet:


*  {
    margin: 0;
    padding: 0;
    font-family: 'poppins', 'sans-serrif';
    box-sizing: border-box;
}

body  {
    background: #001e4d;
}

.app  {
    background: #fff;
    width: 90%;
    max-width: 600px;
    margin: 100px auto 0;
    border-radius: 10px;
    padding: 30px;
}

.app h1  {
     font-size: 25px;
     color: #001e4d
     font-weight: 600
     border-bottom: 1px solid #333;
     padding-bottom: 30px;     
}

.quiz  {
    padding: 20px 0;

}

.quiz h2  {
    font-size: 18px;
    color: #001e4d
    font-weight: 600
}

.btn  {
    background: #fff;
    color: #222;
    font-weight: 500;
    width: 100%; 
    border: 1px solid #222;
    padding: 10px;
    margin: 10px 0; 
    text-align: left;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s; 
}

.btn:hover:not([disabled])  {
    background: #222;
    color: #fff;
}

.btn:disabled {
    cursor: no-drop;
}

#next-btn  {
    background: #001e4d;
    color: #fff;
    font-weight: 500;
    width: 150px;
    border: 0;
    padding: 10px;
    margin: 20px auto 0;
    border-radius: 4px;
    cursor: pointer;  
    display: none;

}

.correct {
    background: #9aeabc;

}

.incorrect {
    background: #ff9393;

}

Let's break down each section and explain what it does

  1. ( * ) : This section applies styles to all elements (*) in the document.

    • margin: 0; padding: 0; : Removes default margins and padding from all elements.

    • font-family: 'poppins', 'sans-serif'; : Sets the default font family to "Poppins" if available, otherwise falls back to a sans-serif font.

    • box-sizing: border-box; : Ensures that padding and border are included in the element's width and height calculations.

  • The body selector defines the background color of the entire page to a dark blue (#001e4d).
  1. .app: This section styles a container element with the class .app. It represents the main quiz content area.

    • background: #fff; : Sets the background color to white.

    • width: 90% :Sets the width to 90% of the viewport.

    • max-width: 600px; : Ensures the element doesn't exceed 600px in width.

    • margin: 100px auto 0; : Adds a 100px top margin, centers the element horizontally, and removes bottom margin.

    • border-radius: 10px; : Creates rounded corners with a 10px radius.

    • padding: 30px; : Adds padding of 30px on all sides.

  2. .app h1: This section styles h1 elements that are children of the .app container. These represent the quiz title.

    • font-size: 25px; : Sets the font size to 25px.

    • color: #001e4d; : Sets the text color to the same dark blue as the body background.

    • font-weight: 600; : Makes the font appear bolder.

    • border-bottom: 1px solid #333; : Adds a solid 1px dark gray border at the bottom.

    • padding-bottom: 30px; : Adds padding below the text.

  3. .quiz: The .quiz selector targets a section containing quiz questions.

    • padding: 20px 0; : Adds padding of 20px on top and bottom.
  4. .quiz h2: The h2 element inside the .quiz section is used for question titles

    • font-size: 18px; : Sets the font size to 18px.

    • color: #001e4d; : Uses the same dark blue color.

    • font-weight: 600; : Makes the text bolder.

  5. .btn: .btn defines styles for buttons used in the quiz application.

    • background: #fff; : Sets the background color to white.

    • color: #222; : Sets the text color to black.

    • font-weight: 500; : Makes the text appear slightly bolder than normal.

    • width: 100%; : Sets the button width to 100% of its container.

    • border: 1px solid #222; : Adds a solid 1px black border.

    • padding: 10px; : Adds padding of 10px on all sides.

    • margin: 10px 0; : Adds a 10px margin on top and bottom.

    • text-align: left; : Aligns the button text to the left.

    • border-radius: 4px; : Creates rounded corners with a 4px radius.

    • cursor: pointer; : Changes the cursor to a pointer hand on hover.

    • transition: all 0.3s; : Enables a smooth transition effect for all styles when hovering or clicking the button.

  6. .btn:hover:not([disabled]: This targets the .btn element only when hovered over with the mouse and when it's not disabled (not([disabled])).

    • background: #222; : Changes the background color to black on hover.

    • color: #fff; : Changes the text color to white on hover.

  7. .btn:disabled: This targets any .btn element that is disabled (disabled).

    • cursor: no-drop; : Changes the cursor to a "not allowed" symbol, indicating the button cannot be interacted with.
  8. #next-btn: This defines styles specifically for an element with the ID #next-btn. This represents a button to navigate to the next question in the quiz.

    • background: #001e4d; : Sets the background color to the same dark blue as the body background.

    • width: 150px; : Sets a fixed width of 150px instead of 100%

    • border: 0; : Removes the solid border.

    • display: none; : This is important! It hides the button by default.

  9. .correct: This section define styles for feedback indicators after a question is answered. It's applied to elements showing a correct answer.

    • background: #9aeabc; : Sets the background color to light green to indicate correct answer.
  10. .incorrect: This section define styles for feedback indicators after a question is answered. It's applied to elements showing an incorrect answer.

    • background: #ff9393; : Sets the background color to light pink to indicate incorrect answer.

This CSS code styles the quiz application with clear layouts, responsive elements, interactive buttons, and likely visual feedback indicators. Now that you have the basic HTML structure and some CSS styling in place, it's time to add interactivity with JavaScript!

3. JavaScript Code: Adding Interactivity

JavaScript allows us to control the dynamic behavior of our quiz application, making it more engaging and user-friendly.

We'll start by creating a JavaScript file from the same folder where your index.html resides (e.g., "my-quiz-app"), right-click again and choose "New File" and name it "script.js". This is another common naming convention for JavaScript files in web development.

Now that you have your script.js file open in VS Code, let's paste the following code snippet:


const questions = [
    {
        question: "Which is the largest animal in the world?",
        answers: [
            { text: "Shark", correct: false },
            { text: "Blue whale", correct: true },
            { text: "Elephant", correct: false },
            { text: "Giraffe", correct: false }
        ]
    },
    {
        question: "Which is the largest desert in the world?",
        answers: [
            { text: "Kalahari", correct: false },
            { text: "Gobi", correct: false },
            { text: "Sahara", correct: false },
            { text: "Antarctica", correct: true }
        ]
    },
    {
        question: "Which is the smallest country  in the world?",
        answers: [
            { text: "Vatican City", correct: true },
            { text: "Bhutan", correct: false },
            { text: "Nepal", correct: false },
            { text: "Sri Lanka", correct: false }
        ]
    },
    {
        question: "Which is the smallest continent in the world?",
        answers: [
            { text: "Asia", correct: false },
            { text: "Australia", correct: true },
            { text: "Arctic", correct: false },
            { text: "Africa", correct: false }
        ]
    }
];

const questionElement = document.getElementById("question");
const answerButton = document.getElementById("answer-buttons");
const nextButton = document.getElementById("next-btn");

let currentQuestionsIndex = 0;
let score = 0;

function startQuiz()  {
    currentQuestionsIndex = 0;
    score = 0;
    nextButton.innerHTML = 'Next';
    showQuestion();
}

function showQuestion() {
    resetState();
    let currentQuestion = questions[currentQuestionsIndex];
    let questionNo = currentQuestionsIndex + 1;
    questionElement.innerHTML = questionNo + ". " + currentQuestion.question;

    currentQuestion.answers.forEach(answer => {
        const button = document.createElement("button");
        button.innerHTML = answer.text;
        button.classList.add("btn"); // Corrected class name
        answerButton.appendChild(button);
        if (answer.correct) {
            button.dataset.correct = answer.correct
        }
        button.addEventListener("click", selectAnswer)
    });
}

function resetState() {
    nextButton.style.display = 'none'
    while(answerButton.firstChild){
        answerButton.removeChild(answerButton.firstChild);
    }
}

function selectAnswer(e) {
    const selectedBtn = e.target
    const isCorrect = selectedBtn.dataset.correct === "true";
    if (isCorrect) {
        selectedBtn.classList.add("correct");
        score++;
    } else {
        selectedBtn.classList.add("incorrect"); 
    }
    Array.from(answerButton.children).forEach(button => {
        if (button.dataset.correct === "true") {
            button.classList.add("correct");
        }
        button.disabled = true;
    });
    nextButton.style.display = "block";
}

function showScore() {
    resetState();
    questionElement.innerHTML = `You scored ${score} out of ${questions.length}!`;
    nextButton.innerHTML = 'Play Again'
    nextButton.style.display = "block";
}

function handleNextButton() {
    currentQuestionsIndex++;
    if (currentQuestionsIndex < questions.length) {
        showQuestion();

    } else {
        showScore();
    }
}

nextButton.addEventListener("click", () => {
    if (currentQuestionsIndex < questions.length) {
        handleNextButton();
    } else {
        startQuiz();
    }
})

startQuiz();

Let's go through the code step-by-step:

  1. Questions Array:
  • questions array contains multiple objects, each representing a question and its corresponding answers.

  • Each question object has a question property for the question text and an answers property, which is an array of objects containing answer options and a boolean correct property indicating whether the answer is correct.

  1. DOM Element Selection:
  • questionElement, answerButton, and nextButton are selected using document.getElementById() to interact with the HTML elements where the question, answer buttons, and next button will be displayed.
  1. Global Variables:
  • currentQuestionsIndex and score are declared to keep track of the current question index and the player's score, respectively.
  1. Functions:
  • startQuiz(): Initializes the quiz by resetting the question index and score, displaying the first question, and setting up the next button.

  • showQuestion(): Displays the current question and its answer options dynamically by iterating through the currentQuestion.answers array and creating buttons for each option.

  • resetState(): Resets the state of the quiz by hiding the next button and removing all answer buttons.

  • selectAnswer(e): Handles the selection of an answer by the player. Updates the score, highlights the selected answer, disables all buttons, and displays the next button.

  • showScore(): Displays the final score once all questions are answered. Resets the state and displays the score.

  • handleNextButton(): Handles the click event of the next button. Either displays the next question or shows the final score.

  1. Event Listeners:
  • Event listeners are added to the next button to handle navigation to the next question or showing the final score.
  1. Initialization:
  • Finally, startQuiz() function is called to initialize the quiz when the page loads.

Conclusion

We've walked you through the exciting journey of building a quiz app from the ground up. You learned how to structure the app's foundation with HTML, add engaging interactivity using JavaScript, and style it visually with CSS.

Throughout this process, you gained valuable hands-on experience. Step-by-step instructions and clear code explanations made building the quiz app a breeze. You've also boosted your JavaScript skills by learning to dynamically generate questions, handle user interactions, and track scores.

This guide has provided a solid foundation for building your quiz application. Don't stop here! Experiment with design, explore adding features like timers or feedback messages, and consider navigation options. The world of web development is vast, so keep learning more about HTML, CSS, and JavaScript to create even more complex, engaging and interactive quizzes.