Quiz Card — Free HTML CSS JS Snippet

Quiz Card · Cards · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Data-driven QUESTIONS array — content fully separated from logic
Lettered options (A-D) generated from the data
Instant feedback: correct in green, wrong choice in red, with marks
Answer locking prevents changing a response after selection
Live score chip and proportional progress bar
Animated SVG results ring via stroke-dasharray/dashoffset
Adaptive performance message based on score band
Restart without reload for repeat attempts

About this UI Snippet

Quiz Card — Multiple Choice, Instant Feedback, Scoring & Results Ring

Screenshot of the Quiz Card snippet rendered live

An interactive quiz is a powerful engagement tool used in e-learning, lead generation, onboarding, and content marketing — the single-question relative is the poll widget. This snippet provides a complete multiple-choice quiz with a progress bar, lettered answer options, instant correct/incorrect feedback, live scoring, and an animated circular results ring at the end showing the percentage score with a performance message.

The data-driven question model

Questions live in a QUESTIONS array, each with a prompt, an options array, and the index of the correct answer. renderQuestion() builds the options as buttons with letter keys (A, B, C, D) from this data. This separation of content from logic means adding, editing, or shuffling questions never touches the rendering or scoring code — you just edit the array.

Instant answer feedback

When an option is clicked, select() locks all options (preventing changes), highlights the correct answer in green with a checkmark, and if the choice was wrong, marks it red with a cross. This immediate reveal is a proven learning reinforcement pattern — showing the right answer at the moment of choice helps retention far better than deferring feedback to the end. The answered flag prevents re-answering after a choice is locked.

Scoring and progression

A correct answer increments the score and updates the points chip in the header. The Next button stays disabled until an answer is chosen, enforcing that the user engages with each question. On the final question, the button relabels to Finish and triggers the results screen instead of advancing.

The animated results ring

The results screen shows a circular SVG progress ring identical in technique to a radial gauge: stroke-dasharray equals the circumference and stroke-dashoffset animates to reveal the proportion matching the score percentage. A short setTimeout before setting the offset ensures the browser registers the initial state, so the ring animates from empty rather than snapping. The percentage counts in the centre and a performance message adapts to the score band.

The progress bar

A linear progress bar at the top fills proportionally to the current question number, giving users a clear sense of how far through the quiz they are — important for completion rates, since an unknown length discourages finishing.

Restart

The Try Again button resets the score, current index, ring offset, and visibility, returning to the first question — enabling repeat attempts without a page reload, which is valuable for practice quizzes and study tools.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not have to trace the quiz's state machine by hand to see how it holds together. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why the answered flag guards select() against re-answering, and why the results ring's stroke-dashoffset animation is set inside a setTimeout rather than immediately after the results panel is shown. The same assistant can help optimize it — ask whether re-querying all .option elements from the DOM on every select() call scales poorly for quizzes with many questions rendered ahead of time, or how to avoid re-running querySelectorAll when the options array is already available in memory. It is just as useful for extending the quiz: ask it to add a per-question countdown timer, shuffle both question order and option order while keeping the correct index accurate, or persist scores across sessions with localStorage. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a multiple-choice quiz card in plain HTML, CSS, and JavaScript with no framework or library.

Requirements:
- Drive the entire quiz from a single QUESTIONS array of objects, each with a question string, an array of option strings, and the zero-based index of the correct option — no question content or scoring logic hardcoded outside this array.
- Render lettered option buttons (A, B, C, D) dynamically from the current question's options array, and show a progress bar whose width is (current question index + 1) divided by total questions.
- On selecting an option: lock all options from further clicks using an answered boolean flag, immediately reveal the correct answer in a distinct color with a checkmark, and if the clicked option was wrong, mark that option in a different color with an X — do not wait for a "submit" step, feedback must be instant on click.
- Keep the Next button disabled until an option has been selected for the current question, and relabel it to "Finish" on the last question.
- On finishing, hide the quiz and show a results panel with an SVG ring whose stroke-dasharray equals its circumference and whose stroke-dashoffset animates from fully-offset (empty) to a value representing the percentage score — the offset change must be deferred by one tick (e.g. a short setTimeout) after the panel becomes visible so the transition actually plays instead of snapping instantly to its end state.
- Show an adaptive message based on the score band (e.g. a distinct message for a perfect score versus a passing score versus a low score), and include a restart function that resets score, current question index, and the ring's offset without a full page reload.

Step by step

How to Use

  1. 1
    Answer each questionClick one of the lettered options. The correct answer turns green and your choice turns red if it was wrong — feedback is instant and the answer locks.
  2. 2
    Advance through the quizAfter answering, click Next to move on. The progress bar fills and the points chip tracks your running score. The button reads Finish on the last question.
  3. 3
    View your resultsAt the end, an animated ring shows your percentage, the exact score, and a message that adapts to how well you did.
  4. 4
    Retake the quizClick Try Again to reset and start over from the first question — no page reload needed.
  5. 5
    Add your own questionsEdit the QUESTIONS array in the JS. Each entry needs a q (prompt), an opts array, and correct (the zero-based index of the right answer). Add as many as you like — everything scales automatically.
  6. 6
    Export for your frameworkClick "JSX" for a React component using useState for the current index and score. Click "Vue" for a Vue 3 SFC with reactive quiz state.

Real-world uses

Common Use Cases

E-learning course knowledge check
Embed quizzes between lessons to reinforce learning. The instant feedback turns each question into a teaching moment, and the results ring gives learners a clear sense of mastery. Persist scores to track progress across a course and gate advancement on a passing percentage.
Lead-generation and marketing quiz funnel
Quizzes like "What kind of developer are you?" drive engagement and capture leads. After the results ring, show an email capture to deliver a personalised result. The completion mechanics and progress bar are tuned to maximise finish rates, which directly drives lead volume.
Onboarding and product knowledge assessment
Use a quiz to verify new employees or users understood onboarding material. The scoring identifies who needs follow-up, and the per-question feedback teaches the correct answer immediately. Export results to an LMS or HR system for compliance tracking.
Wire to a question bank and randomisation
Load questions from an API instead of the hardcoded array, and shuffle both the question order and the options (remember to track which shuffled index is correct). Add a timer per question, partial credit, or weighted scoring. The data-driven model makes all of these additive.
Study quiz state machines and SVG result rings
The snippet demonstrates a clean quiz state machine (render → answer → lock → advance → results), data-driven option rendering, and the animated SVG ring technique. These patterns apply to surveys, assessments, polls, and any step-based interactive flow.
Trivia game or community challenge
Build a daily trivia widget or community quiz challenge. Add a leaderboard by posting scores to a backend, a streak counter for consecutive correct answers, and shareable result cards so players can post their percentage to social media and pull in new participants.

Got questions?

Frequently Asked Questions

Edit the QUESTIONS array at the top of the JavaScript. Each question is an object with three keys: q (the question text), opts (an array of answer strings, typically four), and correct (the zero-based index of the right answer within opts). Add as many question objects as you want — the counter, progress bar, scoring, and results all scale to the array length automatically with no other changes.

The ring uses stroke-dasharray set to its circumference and stroke-dashoffset to control how much is revealed. It starts fully offset (empty). When the results screen shows, a short setTimeout delays setting the final offset by one tick. This delay lets the browser paint the empty state first, so the transition animates smoothly from 0 to the score percentage instead of snapping instantly to the final value — the same technique used for any reveal-on-mount CSS transition.

Shuffle the QUESTIONS array with a Fisher-Yates shuffle before the quiz starts. To shuffle answer options too, map each question's opts into objects that remember whether each was the correct one, shuffle that array, then derive the new correct index from where the originally-correct option landed. Track the correct answer by identity rather than a fixed index so shuffling never breaks scoring.

Store current (question index), score, and answered in useState. Render the current question from QUESTIONS[current]. On option click, if not answered, set answered true, update the option styles via derived state (compare each index to the correct answer), and increment score for a correct pick. Next increments current or, on the last question, flips a showResults flag. Compute the ring dashoffset from score / total for the results view.