Building an Engaging Multichoice Quiz App with Vanilla JavaScript
Hey dev.to community! 👋 Today I'm excited to share a project I've been working on - an interactive multichoice quiz application built with pure HTML, CSS, and JavaScript.
Check it out here: Quizzical Quiz App
The Origin Story
We've all been to those gatherings where everyone's glued to their phones instead of talking to each other. That's exactly what sparked this project - I wanted to create something that could bring people together while still satisfying our collective tech addiction.
The Quizzical app emerged from a desire to blend education with entertainment. Because let's face it - learning is way more fun when it feels like a game! 🎮
Key Features
What makes this quiz app stand out in a sea of similar applications?
- Dynamic Categories - Pull questions from numerous knowledge domains
- Difficulty Selection - Choose your challenge level
- Custom Question Count - Fit the quiz to your available time
- Dark/Light Mode - Easy on the eyes, whatever time of day
- Real-time Progress Tracking - Visual feedback on your quiz journey
- Timed Quizzes - Add that perfect pressure element
- Detailed Review System - Learn from your mistakes
- Social Sharing - Challenge friends with your scores
The Tech Stack
This project was intentionally built without frameworks to showcase what's possible with vanilla web technologies:
- HTML5 for structure
- CSS3 with custom properties for styling
- Vanilla JavaScript for functionality
- Fetch API for retrieving questions from Open Trivia DB
No React, no Vue, no Angular - just pure web fundamentals.
Architecture & Code Organization
The application follows a simple but effective architecture:
-
State Management: A central
quizData
object maintains the entire application state - Screen Management: Helper functions control which screen is displayed
- Event Handling: Carefully separated event listeners manage user interactions
- API Integration: Asynchronous functions fetch questions and categories
The UX Touches That Matter
Small details can make a big difference in user experience:
Thoughtful Animations
Subtle transitions between screens create a fluid experience without overwhelming users. The progress bar smoothly fills as you advance through questions.
Instant Feedback
When selecting answers, users get immediate visual feedback. The review screen later shows a comprehensive breakdown of performance.
Accessibility Considerations
High contrast ratios, keyboard navigation support, and semantic HTML ensure the app is usable by everyone.
Code Highlights
Here's a snippet of how the question display logic works:
function showQuestion(index) {
const question = quizData.questions[index];
quizData.currentQuestionIndex = index;
// Set question text
questionText.innerHTML = question.question;
// Create answer options
answersContainer.innerHTML = '';
// Combine and shuffle answers
const allAnswers = [question.correctAnswer, ...question.incorrectAnswers];
const shuffledAnswers = shuffleArray(allAnswers);
shuffledAnswers.forEach((answer, answerIndex) => {
const answerElement = document.createElement('div');
answerElement.className = 'answer-option';
// Check if this option was previously selected
if (quizData.userAnswers[index] === answer) {
answerElement.classList.add('selected');
}
answerElement.innerHTML = `
<div class="answer-marker"></div>
<div class="answer-text">${answer}</div>
`;
answerElement.addEventListener('click', () => selectAnswer(answer, answerElement));
answersContainer.appendChild(answerElement);
});
updateQuizInfo();
}
Dev Challenges & Solutions
Building this wasn't without its challenges:
Challenge 1: Handling API Inconsistencies
The Open Trivia DB sometimes returns HTML entities in questions and answers. To solve this, I used base64 encoding in the API request and decoded responses client-side.
Challenge 2: Timer Implementation
Creating a reliable timer that persists across question changes required careful state management. The solution was to track start time and calculate elapsed time on each interval.
Challenge 3: Dynamic UI Updates
Ensuring the UI stays in sync with the application state took some planning. The solution was creating update functions that run after any state change.
Lessons Learned
This project reinforced several important development principles:
- State Management Matters - Even in a "simple" app, proper state management is crucial
- Progressive Enhancement - Build core functionality first, then add features
- Test Early, Test Often - Cross-browser testing caught several issues early
- User Feedback is Gold - Early testers helped identify UX issues I was blind to
What's Next?
I'm considering several enhancements:
- Multiplayer Mode - Real-time competition between friends
- Custom Quiz Creation - Allow users to create and share their own quizzes
- Offline Support - Service workers for offline functionality
- Advanced Statistics - Track performance over time
- PWA Features - Make the app installable on devices
Your Turn!
I'd love to hear your thoughts and suggestions for this project! What features would you like to see added? Any other improvements you can think of?
Try out the Quizzical Quiz App and let me know what you think in the comments!
Happy coding! 💻
Just took a quiz on the webapp. A seamless experience.