Basic example · Single answer

Two-attempt single-answer practice quiz

Test validation, targeted retry feedback, answer reveal, and recovery with a focused practice question built on native radio buttons.

Scenario

An introductory accessibility course asks learners to identify the native element that already provides form-action semantics and keyboard behavior.

User goal: understand the feedback after a missing or incorrect answer, then complete the question.

Try it

  1. Activate Check answer without selecting an option to inspect validation feedback.
  2. Select <div> and check the answer to reveal retry feedback.
  3. Change the selection to <button> and check again, then reset the completed question.
  4. After resetting, select <div>, check it, then choose Show correct answer.
  5. After another reset, check <div> twice to inspect the final incorrect result.
  6. Use Tab to reach controls and arrow keys to change the radio selection.

Practice question

This example uses practice mode, two attempts, an attempt progress indicator, and answer reveal after the first incorrect check.

Which HTML element should trigger a form action?

Choose one answer.

Need a hint?

Prefer the native element whose built-in role matches the action.

Accessibility notes

  • A native fieldset, legend, labels, radio buttons, and buttons provide the semantic baseline.
  • Arrow keys change the selected radio option; Tab moves to the next control.
  • Instructions, answer feedback, and explanations are associated with the relevant controls.
  • Polite status text announces results while focus stays in the current interaction.
  • Visible text reinforces correct and incorrect states without relying on color.
  • The page has no required motion and includes a no-JavaScript answer fallback.

Developer notes

The root is [data-a11y-quiz]. Answer cards use .a11y-quiz__answer, inputs use .a11y-quiz__input, and the correct card carries data-correct="true".

For a package integration, use the semantic form markup with:

import { createQuizForm } from "a11y-quiz-form";
import "a11y-quiz-form/styles.css";

const form = document.querySelector("[data-a11y-quiz]");

if (form instanceof HTMLFormElement) {
  createQuizForm(form);
}

The demo form itself begins with:

<form data-a11y-quiz
  data-max-attempts="2"
  data-show-progress="true"
  data-disable-check-until-answered="false">
  ...
</form>

This source demo imports ../dist/index.js and ../dist/styles.css. It keeps Check answer available before selection so validation feedback is testable. One instance manages one question; score aggregation and persistence remain application concerns.