Skip to content

Mchoice accessibility fixes - #1413

Open
ascholerChemeketa wants to merge 3 commits into
RunestoneInteractive:mainfrom
ascholerChemeketa:mchoice-accessibility
Open

Mchoice accessibility fixes#1413
ascholerChemeketa wants to merge 3 commits into
RunestoneInteractive:mainfrom
ascholerChemeketa:mchoice-accessibility

Conversation

@ascholerChemeketa

Copy link
Copy Markdown
Contributor

Changes for mchoice screen reader accessibility.

General lessons:

  • Legends need to be first thing in fieldsets.
  • Unicode characters like the purple check and X provide issues visually (contrast) and for screen readers. The "X" is pronounced "multiplied".
  • MathJax does not work correctly inside native labels.

Copilot AI lite review requested due to automatic review settings August 24, 2026 14:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Multiple Choice (mchoice) accessibility for screen readers by adjusting form structure, avoiding problematic Unicode symbols in feedback, and handling MathJax content without placing it inside native <label> elements.

Changes:

  • Reorders fieldset/legend rendering so the legend is read before options by screen readers.
  • Adds a MathJax-specific option DOM structure (wrapper + visually hidden label + separate content span) and corresponding CSS/test updates.
  • Replaces feedback emoji (✔️/✖️) with Material Symbols icons plus visually hidden “Feedback: …” text.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
bases/rsptx/interactives/runestone/mchoice/js/mchoice.js Reworks option rendering (MathJax vs non-MathJax), moves legend before options, and updates feedback markup for accessibility.
bases/rsptx/interactives/runestone/mchoice/css/mchoice.css Extends option styling to cover the new .mchoice-option spans and .rs-radio-group wrapper.
bases/rsptx/interactives/runestone/mchoice/test/mchoice.test.js Adds/updates tests for the new MathJax option structure and updated feedback icon markup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

// Add fieldset and legend for accessibility - legend must come before the options
// so screen readers read the legend first.
this.optsFieldSet = document.createElement("fieldset");
this.optsFieldSet.setAttribute("role", "radiogroup");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a good one to follow.

input_type = "checkbox";
}
// Creates input DOM elements.
this.optionArray = []; // Array with an object for each option containing its input and content div.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer make two items for MJ

Comment on lines +256 to +258
// To provide screen reader support for mathjax content, we need to pull the mathjax out of
// the label and put it in a separate span. The label will have a visually hidden span that
// describes the option, and the mathjax will be in a separate span that is aria-hidden.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds reasonabl

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer relevent

Comment on lines +262 to +266
const group = document.createElement("div");
group.className = "rs-radio-group";

const input = document.createElement("input");
input.type = inputType;

@ascholerChemeketa ascholerChemeketa Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer relevant

if (correct) {
this.feedBackDiv.innerHTML = "✔️ " + feedbackText;
this.feedBackDiv.className = "alert alert-info"; // use blue for better red/green blue color blindness
this.feedBackDiv.innerHTML = `<span class="visuallyhidden">Feedback: Correct</span><span class="material-symbols-outlined" aria-hidden="true">check_circle</span>` + feedbackText;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just noticing a small inconsistency, it seems that the incorrect symbol is kind of in-line but the correct symbol is always on its own line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They were always the same. The issue is the You gave 2 answers and got 2 correct of 3 needed. text that is there inline in the incorrect case. The list is a block element and always will be on a new line.

Forced icons to be blocks so they always are on their own line.

@ascholerChemeketa
ascholerChemeketa marked this pull request as draft August 24, 2026 16:47
@ascholerChemeketa

Copy link
Copy Markdown
Contributor Author

Will check into those. May revise MathJax approach...

Marked as a draft while doing that.

Copilot AI review requested due to automatic review settings August 24, 2026 22:49
@ascholerChemeketa
ascholerChemeketa marked this pull request as ready for review August 24, 2026 22:49
@ascholerChemeketa

Copy link
Copy Markdown
Contributor Author

Updated to address comments and using a similar scheme to matching/cardsort for mathjax in labels

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

input_type = "checkbox";
}
// Creates input DOM elements.
this.optionArray = []; // Array with an object for each option containing its input and content div.
Comment on lines +268 to +270
visibleContent = document.createElement("span");
visibleContent.innerHTML = `${optionLetter}. ${content}`;
label.append(input, accessibleText, visibleContent);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like we might want to address this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants