Quizzes and Tabs
Two more built-in components: <question> for multiple-choice quizzes and surveys, and <tabs-container> for grouped content with switchable views.
Quizzes
A quiz is a <question> block with one or more <answer> children. Marking an answer as correct makes it the right answer.
Single-choice (radio buttons)
<question id="q-single-demo" type="single">
<p>Which keyword defines a function in Python?</p>
<answer>function</answer>
<answer correct>def</answer>
<answer>fn</answer>
<answer>lambda</answer>
</question>
Renders as:
Students see a list with radio buttons; can pick one. Click Check to see if it's right.
Multi-choice (checkboxes)
<question id="q-multi-demo" type="multi">
<p>Which of these are immutable in Python?</p>
<answer correct>tuple</answer>
<answer>list</answer>
<answer correct>str</answer>
<answer correct>frozenset</answer>
<answer>dict</answer>
</question>
Renders as:
Students must pick all and only the correct answers to be marked correct.
Free-text answer
<question id="q-text-demo" type="text">
<p>What is the output of <code>print(2 ** 10)</code>?</p>
<answer correct>1024</answer>
</question>
Renders as:
Student types an answer; case-insensitive comparison against the correct answer(s). You can list multiple <answer correct> to accept variations:
<question id="q-text-variants-demo" type="text">
<p>What is the capital of Switzerland?</p>
<answer correct>Bern</answer>
<answer correct>Berne</answer>
</question>
Renders as:
A different free-text mechanism exists tooThis is exact/variant string matching for short factual answers. For grading a student's predicted output of a piece of code — with partial credit and a diff, rather than exact match — see the predict-output variant of
<question type="text">in Code Editors & Scoring. Same tag, different purpose.
Question attributes
| Attribute | Values | Effect |
|---|---|---|
id | string | Unique ID per page; used to track student responses |
type | single / multi / text / number / range | Question style |
points | number (default 1) | Score weight |
feedback-correct | string | Custom message shown on correct answer |
feedback-incorrect | string | Custom message shown on incorrect answer |
<question id="q-feedback-demo" type="single" points="2"
feedback-correct="Genau! In Python ist `def` das Schlüsselwort."
feedback-incorrect="Hinweis: Die Antwort beginnt mit dem Buchstaben d.">
<p>Welches Schlüsselwort definiert eine Funktion in Python?</p>
<answer>function</answer>
<answer correct>def</answer>
<answer>fn</answer>
</question>
Renders as:
Welches Schlüsselwort definiert eine Funktion in Python?
function def fnWhat students see
- Question text + answer choices
- Check button to submit
- ✓ green or ✗ red feedback after submitting
- Custom feedback message (if set)
- Score for that question
Their answer is saved per-student-per-page; coming back later shows their previous response.
Scoring options
points (default 1) sets a question's score weight — the max points it contributes. How a question earns those points depends on its type:
single/multiauto-score full points on an exact match against thecorrectanswer(s) — no partial credit for choice questions.textauto-scores on a case-insensitive match against any<answer correct>variant.- Sliders (
number/range) auto-grade against a target, with banded partial credit:
<question id="q-slope-demo" type="number" points="2" expected="-1" tolerance="0.15">
<p>What is the slope of the line shown in the plot?</p>
<answer from="0.9" feedback="Exact, or close enough to count as exact."></answer>
<answer from="0.5" feedback="Right direction, but check your calculation."></answer>
</question>
type="number" expected="-1" tolerance="0.15" sets a single target value with a tolerance band; type="range" expected="-1..1" instead accepts any answer in that range. <answer from="..."> bands go from best to worst — the first one the student's answer clears (reading top to bottom) determines their feedback and partial score.
All auto-scored results are teacher-overridable when scoring — see below.
Surveys (ungraded questions)
Not every question needs a right answer. A <question> with no <answer correct> (or no scored slider target) collects a response without grading it — useful for opinion polls, "how confident do you feel about this topic," or exit tickets. Students still see their own past response when they return; there's just no ✓/✗ feedback because there's nothing to be right or wrong about.
What you can see as the teacher
For students signed in to a class, quiz responses feed into the same submissions view as auto-scored code (see Code Editors & Scoring):
- Submissions interface (
Dashboard → Classes → Submissions) — each student's answers and score, per question - Per-student detail — see exactly what they selected or typed
- Numeric overrides — adjust the auto-scored points for a question, e.g. to award partial credit a slider band didn't quite capture
- Comments — leave feedback per submission
Auto-scored quiz results sit alongside python-check and predict-output results in the same review flow, so you get one place to see how a student did across an entire page rather than jumping between component types.
Tabs
Tabbed containers group related content with switchable views. Useful for: language alternatives, OS-specific instructions, beginner/advanced versions of the same content, before/after comparisons.
Basic syntax
<tabs-container>
<tab-item label="Python">
Standard Python solution.
```python
print("Hello")
```
</tab-item>
<tab-item label="JavaScript">
JavaScript equivalent.
```javascript
console.log("Hello")
```
</tab-item>
<tab-item label="Rust">
Rust version (compiled).
```rust
println!("Hello");
```
</tab-item>
</tabs-container>
Renders as:
Standard Python solution.
print("Hello")
JavaScript equivalent.
console.log("Hello")
Rust version (compiled).
println!("Hello");
Students see a tab bar at the top with the three labels; clicking switches between them.
Tabs can hold any content
Markdown, code blocks, code editors, callouts, images, math — anything that works in the body of a page works inside a <tab-item>.
<tabs-container>
<tab-item label="Description">
The Pythagorean theorem states that for a right triangle:
$a^2 + b^2 = c^2$
</tab-item>
<tab-item label="Try it">
```python editor id="pythagoras"
a, b = 3, 4
c = (a**2 + b**2) ** 0.5
print(f"c = {c}")
```
</tab-item>
<tab-item label="Proof">
> [!example] Geometric proof
> Take four right triangles with legs $a$ and $b$ ...
</tab-item>
</tabs-container>
Default open tab
Add default to one tab to make it open initially (otherwise the first tab is open by default):
<tabs-container>
<tab-item label="macOS">macOS instructions</tab-item>
<tab-item label="Windows" default>Windows instructions</tab-item>
<tab-item label="Linux">Linux instructions</tab-item>
</tabs-container>
Tabs cheat sheet
| Goal | Syntax |
|---|---|
| Tabbed container | <tabs-container>...</tabs-container> |
| Individual tab | <tab-item label="Label">content</tab-item> |
| Default open tab | <tab-item label="..." default> |
| Embed a code editor in a tab | Standard ```python editor inside the <tab-item> |
When to use which
| Situation | Use |
|---|---|
| Test a student's recall of a fact | <question type="single"> or type="text"> |
| Test programming behavior | python editor + python-check (Code Editors & Scoring) |
| Test tracing/predicting code output | <question type="text"> with an ```expected block (Code Editors & Scoring) |
| Collect opinion, no right answer | <question> with no correct answer (survey) |
| Show the same content in multiple flavors | <tabs-container> |
| Hide hint until clicked | Collapsed callout (> [!tip]-) |
| Hide a long solution | Collapsed callout with code block |
For self-scoring code exercises, python-check is much more powerful than <question>. For factual recall and discrete-answer questions, <question> is faster to write.