Building a Quiz App with HTML, CSS and Vanilla JavaScript

Building a Quiz App with HTML, CSS and Vanilla JavaScript

Still on the 20 days JavaScript Challenge, I built a Quiz App with HTML, CSS and Vanilla JavaScript and in this article I will explain how I built this app. I hope you learn a lot from it because the explanation will be very detailed and links to relevant sources would be mentioned.

Let's start by explaining the Quiz App and how it works. The quiz app has 10 questions in total and it displays the questions in the order of their number, So Immediately you click an option and click on the next button your option will be saved and the last page shows your score over 10. So let's go on to see how this amazing app was made😜

The Three major building blocks of this app are the;

  1. HTML Structure.
  2. CSS Styling and,
  3. The major brain which is the JavaScript Functionality.

HTML Structure

The user interface(ui) design of this app is not too complex just the basic understanding of HTML and I will Share the code snippet below, The purpose of having our HTML code is so that the page will have structure like the skeleton of a human being. There are also id's and classes attached to the questions and answers boxes in order to be easy for us to manipulate the DOM with our JavaScript.

Find attached the code snippet

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./styles.css" />
    <title>My Quiz App</title>
  </head>
  <body>
    <h1>My Quiz App</h1>

    <div class="quiz-container" id="quiz">
      <div class="quiz-header">
        <h2 id="question">Question Text</h2>
        <ul>
          <li>
            <input type="radio" class="answer" name="answer" id="a" />
            <label for="a_text" id="a_text">Question</label>
          </li>
          <li>
            <input type="radio" class="answer" name="answer" id="b" />
            <label for="b_text" id="b_text">Question</label>
          </li>
          <li>
            <input type="radio" class="answer" name="answer" id="c" />
            <label for="c_text" id="c_text">Question</label>
          </li>
          <li>
            <input type="radio" class="answer" name="answer" id="d" />
            <label for="d_text" id="d_text">Question</label>
          </li>
        </ul>
      </div>
      <!-- Submit Button -->
      <button id="submit" type="submit">Next</button>
    </div>

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

CSS Styling

CSS can be likened to the flesh of a human being, much more than the skeleton we need flesh so that we can be presentable and interact with our environment. The Styling, Colors, nice Font and aligning of this app was achieved by using CSS. One of the major CSS properties used in this app is Flexbox and it is a really good property that can be used to layout and alignment of content without using floating or positioning.

Below is the code snippet that explains how the CSS was used to style the page

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap');

* {
  box-sizing: border-box;
}

body {
  background-color: #b8c6db;
  background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%);
  font-family: 'Poppins', sans-serif;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-evenly;
  font-family: 'Poppins', sans-serif;
  min-height: 100vh;
}

.quiz-container {
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  width: 800px;
  max-width: 85%;
}

.quiz-header {
  padding: 2rem;
}

h2 {
  text-align: center;
  padding: 1rem;
  margin: 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

ul li {
  cursor: pointer;
  font-size: 1.1rem;
  margin: 1rem;
}

ul li input {
  cursor: pointer;
}

ul li label {
  cursor: pointer;
}

button {
  background: yellow;
  border: none;
  color: black;
  display: block;
  font-family: inherit;
  font-size: 1.3rem;
  width: 100%;
  padding: 1rem;
}

The Brain Behind Our App

Now let's learn how to build what makes the ui functional and interactive, like from our example earlier Human beings don't just have Skeleton and Flesh but one characteristics of Human Being is the ability to move from one place to another. So the purpose of using JavaScript is to make it functional.

The whole process of the functionality was achieved in just 6 steps and these steps would be explained well with code snapshot to explain what I am writing about.

These Steps are ; Step 1: Creating a Questions, Options and Answer Object so that we can display it dynamically on our user interface. These objects are placed in an array called quizData so that it can be easy to work with and below is the code snippet that shows what I am writing about;

// The Quiz Questions
const quizData = [
  {
    question: "How old is Nigeria?",
    a: "60",
    b: "45",
    c: "42",
    d: "61",
    correct: "a",
  },
  {
    question: "What is the full meaning of CSS?",
    a: "Cascading Style Server",
    b: "Cascade Styling Surface",
    c: "Cascading Surface Sheet",
    d: "Cascading Style Sheets",
    correct: "d",
  },
  {
    question: "What is the most popular programming language in 2020?",
    a: "Java",
    b: "PHP",
    c: "Python",
    d: "JavaScript",
    correct: "d",
  },
  {
    question: "Who is the President of America?",
    a: "Joe Biden",
    b: "Donald Trump",
    c: "Ivan Saldano",
    d: "Mihai Andrei",
    correct: "a",
  },
  {
    question: "What does HTML stand for?",
    a: "Hypertext Markup Language",
    b: "Cascading Stylesheet",
    c: "JavaScript Object Notation",
    d: "Hyper Markup Language",
    correct: "a",
  },
  {
    question: "What year was JavaScript launched?",
    a: "1998",
    b: "1993",
    c: "1995",
    d: "2000",
    correct: "c",
  },
  {
    question: "When was Buhari elected as Nigerian President?",
    a: "2010",
    b: "2016",
    c: "2015",
    d: "2019",
    correct: "c",
  },
  {
    question: "All these are Server Side Language except?",
    a: "HTML",
    b: "PHP",
    c: "Node.js",
    d: "Ruby on rails",
    correct: "a",
  },
  {
    question: "All these are JavaScript Framework except?",
    a: "Laravel",
    b: "React.js",
    c: "Node.js",
    d: "Vue.js",
    correct: "a",
  },
  {
    question: "Bonus mark, click on option a?",
    a: "a",
    b: "b",
    c: "c",
    d: "d",
    correct: "a",
  },
];

So now that we have our questions then we are a step closer to our target, let us go to the next step...

Step 2: Getting where the questions and options will be populated on our ui by using document.getElementById() and document.querySelectorAll() in JavaScript. This is a process of interacting with the DOM directly. So Id's and classes were added to our HTML code as mentioned earlier so that this process will be very easy to carry out. Below is a code snippet showing what I just explained.

// Getting where to insert the questions
const quiz = document.getElementById("quiz");
const answerEls = document.querySelectorAll(".answer");
const questionEl = document.getElementById("question");
const a_text = document.getElementById("a_text");
const b_text = document.getElementById("b_text");
const c_text = document.getElementById("c_text");
const d_text = document.getElementById("d_text");
const nextButton = document.getElementById("submit");

You might be wondering why I used document.querySelectorAll() and document.getElementById(), They are both used to interact with the DOM but document.querySelectorAll() was used because there is more than one class called answer so it makes it easier and better to use it, But on the other hand document.getElementById() is used for a unique Id because logically you cant have no two id's that are the same value.

So after getting where we want to populate and the quiz questions we want to use with their answers, let's now move to the next step;

Step 3: Creating a JS Function that loads the quiz questions and options but before let us initiate a counter for our quiz questions so that it can display questions for every count. The major work to be done here is to just pick where we want to populate the questions and insert what is in the question object to it using the .innerText in JavaScript. And in the two previous steps we created the questions and got where to populate it. So below is the code snippet that explains what we need to do;

let currentQuiz = 0;

loadQuiz();

// Function that loads question
function loadQuiz() {
  // First Deselect Default Option
  deselectAnswer();

  const currentQuizData = quizData[currentQuiz];

  questionEl.innerText = currentQuizData.question; // Main Question
  a_text.innerText = currentQuizData.a; // Option a
  b_text.innerText = currentQuizData.b; // Option b
  c_text.innerText = currentQuizData.c; // Option c
  d_text.innerText = currentQuizData.d; // Option d
}

Step 4: The next step is to deselect the checkbox for the options at default by looping through it with the forEach() method in JaavaScript and as we can see that in the previous step function we called the deselectAnswer() function in it so that as the questions load it deselects any option until you now select an option by yourself. Below is also the Code snapshot of what I am saying.

// Deselection Default Option
function deselectAnswer() {
  answerEls.forEach((answerEl) => {
    answerEl.checked = false;
  });
}

Step 5: Now let us write a function to get the selected value that the user picks, we are going to loop through the options again like we did for the deselect with the forEach() method and when the option is checked we then store it in a variable called answer

// Get Selected Option
const getSelected = () => {
  let answer;

  answerEls.forEach((answerEl) => {
    if (answerEl.checked) {
      answer = answerEl.id;
    }
  });

  return answer;
};

Step 6: This is the final step and what we want to achieve is that as the option is selected and the next button is clicked it checks the answer and increment your score as you progress and at the end it displays your score but the score is initially set to zero so that we can increment it easily. So we are going to add an event listener to the button. I believe if you see the code it would be easier to understand.

nextButton.addEventListener("click", () => {
  // Check to see the answer
  const answer = getSelected();

  if (answer) {
    if (answer === quizData[currentQuiz].correct) {
      score++;
    }
  }
  // Increment Upon Click
  currentQuiz++;

  if (currentQuiz < quizData.length) {
    loadQuiz();
  } else {
    quiz.innerHTML = `
    <h2>You answered ${score} out of ${quizData.length} correctly.</h2>
     <button onclick="location.reload()">Retake Quiz!</button>`;
  }
});

Conclusion

With these 6 steps our Quiz App will be very functional but we can later add more functionalities like authentication but for the scope of the project we have achieved what we want to do. I really enjoyed the building of this app because it is really cool and fun. You can get the source code of this web app here and the hosted link on netlify by clicking here .

Thanks for reading through...