A11y Considerations in Math on the Web
by Manuel Sánchez published on
Maybe it has happened to you that you wanted to write some formulas in HTML to display on a website, and even though there are multiple ways to do it, accessibility is often not considered in the process. How the formula is read by screen readers is crucial to ensure that we don't leave anyone behind. And the main assistive technologies are in different stages, as we will see.
The web is full of many different and interesting approaches for representing formulas. To name a few, we have TeX/LaTeX source rendered in the browser in different ways, like MathJax or KaTeX, we can use Unicode math, Canvas/WebGL or even simple PNG/JPG or SVG pictures. However, using native MathML is usually one of the best options for this task, even if it wasn’t initially designed for the web. Some of its advantages are that it has its own syntax, MathML, which provides various elements that give the correct semantics to the different parts of a formula, it has good screen reader support, works without JavaScript dependencies, and can be used beyond the browser, as in EPUB or braille/math speech tooling.
Let's take the famous Pythagorean Theorem as an example.
Pythagorean Theorem
The following example is a visual representation of the formula together with the MathML code.
<math xmlns="http://www.w3.org/1998/Math/MathML">
<msup>
<mi>a</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>=</mo>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</math>Unlike plain HTML with sup or span, which only describe presentation, MathML defines each role explicitly:
mathrepresents the entire mathematical expression.msupdefines a superscript relationship (a base and an exponent).miis a mathematical identifier, typically a variable such as a, b, or c.mnis a mathematical number, like 2.mois a mathematical operator, such as + or =.
Other alternatives, like the ones mentioned above, may offer similar capabilities, but they typically rely on an assistive or hidden MathML layer. In practice, MathML remains the only web-standard markup that expresses mathematical roles natively in the DOM.
With this approach, the accessibility tree shows good semantics and VoiceOver knows well what to do.

However, as we will see throughout the article, screen reader support for the math tag varies across assistive technologies. VoiceOver seems to be doing a pretty good job, JAWS also makes it easy for both speech and braille, and NVDA needs an add-on to make it work called MathCat because if not, the math tag will be ignored. A major pull request (#18323) was merged on 17 November 2025 which integrates MathCAT into NVDA core, meaning users won’t have to find/install a separate add-on to handle math.
How screen readers interpret the formula
NVDA + Firefox (Windows with MathCAT add-on)
region a squared plus b squared is equal to c squared spaceVoiceOver + Safari (Mac)
a squared + b squared = c squared, with 5 items, mathsVoiceOver + Safari (iOS)
a squared plus b squared equals c squared, MathLet's look at a more complicated case. Instead of just displaying the formula, let's see how to actually prove it and how screen readers will announce it.
<math display="block">
<semantics>
<mtable>
<!-- Step one -->
<mtr>
<mtd>
<msup>
<mrow>
<mo>(</mo>
<mi>a</mi>
<mo>+</mo>
<mi>b</mi>
<mo>)</mo>
</mrow>
<mn>2</mn>
</msup>
</mtd>
<mtd>
<mo>=</mo>
</mtd>
<mtd>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<mn>4</mn>
<mo>⋅</mo>
<mo>(</mo>
<mfrac>
<mn>1</mn>
<mn>2</mn>
</mfrac>
<mi>a</mi>
<mi>b</mi>
<mo>)</mo>
</mtd>
</mtr>
<!-- Step two -->
<mtr>
<mtd>
<msup>
<mi>a</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<mn>2</mn>
<mi>a</mi>
<mi>b</mi>
<mo>+</mo>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
</mtd>
<mtd>
<mo>=</mo>
</mtd>
<mtd>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<mn>2</mn>
<mi>a</mi>
<mi>b</mi>
</mtd>
</mtr>
<!-- Step three -->
<mtr>
<mtd>
<msup>
<mi>a</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
</mtd>
<mtd>
<mo>=</mo>
</mtd>
<mtd>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</mtd>
</mtr>
</mtable>
<annotation encoding="application/x-tex">
\begin{aligned} (a + b)^2 &= c^2 + 4 \cdot \left( \frac{1}{2} ab \right)
\\ a^2 + 2ab + b^2 &= c^2 + 2ab \\ a^2 + b^2 &= c^2 \end{aligned}
</annotation>
</semantics>
</math>This proof example just added several MathML elements that go beyond simple identifiers and operators. Each of these adds meaning to the expression, which is why assistive technologies can navigate the structure so precisely. For example:
mtable,mtrandmts: these directly mirror HTML'stable,trandtdbut are math-specific. They tell the accessibility tree: "this is a mathematical table with aligned steps," not just a generic layout table. Screen readers can move row-by-row, so each step of the proof becomes navigable.mrow: groups expressions together. For example(a + b)is wrapped in anmrowto indicate that the parentheses and the interior form a single unit before exponentiation.mfrac: defines an actual mathematical fraction, not just text with a slash. This allows speech engines to say "one half" instead of "one over two" depending on preferences and locale.semantics: this is key. It wraps the expression and lets you attach alternative meanings or encodings. Assistive technologies prefer the first child (your visual MathML), but can fall back to the annotation if needed.annotation: stores auxiliary information. In this case, the TeX version of the proof. It does not affect the visual rendering in the browser. Instead, it's metadata for tools that consume MathML, like converters, EPUB readers, or braille translators.
Check out how this is announced by different screen readers!
How screen readers interpret the proof
NVDA + Firefox (Windows with MathCAT add-on)
3 lines line 1 left parenthesis a plus b right parenthesis squared is equal to c squared plus 4 times 1 half a bline 2 a squared plus 2 a b plus b squared is equal to c squared plus 2 a b
line 3 a squared plus b squared is equal to c squared
VoiceOver + Safari (Mac)
Table start, Row 1, Column 1, ( a + b ) squared, Row 1, Column 2, =, Row 1, Column 3, c squared + 4 · ( fraction start, 1 over 2, end of fraction, a b ), Row 2, Column 1, a squared + 2 a b + b squared, Row 2, Column 2, =, Row 2, Column 3, c squared + 2 a b, Row 3, Column 1, a squared + b squared, Row 3, Column 2, =, Row 3, Column 3, c squared, table end, mathsVoiceOver + Safari (iOS)
1 table, table start, Row 1, Column 1, a plus b squared, Row 1, Column 2, equals, Row 1, Column 3, c squared plus 4 dot fraction start 1 over 2, end of fraction, a b, Row 2, Column 1, a squared plus 2 a b plus b squared, Row 2, Column 2, equals, Row 2, Column 3, c squared plus 2 a b, Row 3, Column 1, a squared plus b squared, Row 3, Column 2, equals, Row 3, Column 3, c squared, table end, MathNote: If you want to deepen your understanding in the topic, Mozilla has a very detailed page about proving the Pythagorean theorem with MathML.
Some A11y Enhancements
We could enhance this by adding an aria-label to a wrapper that provides some information about the following formula, especially when it's a well-known one. By using a section with an aria-label or aria-labelledby together with another element giving the accessible name, we automatically insert a region into the accessibility tree.
<section aria-labelledby="section-1-heading">
<h2 id="section-1-heading">Pythagorean Theorem</h2>
<math xmlns="http://www.w3.org/1998/Math/MathML"> ... </math>
</section>Also, for users who zoom the browser up to 400%, we might want to add a max-width: 100% and overflow-x: auto, so that the formula remains readable, does not break the page and we allow horizontal scrolling only inside the math block, and not at the entire page level.
Conveying mathematical meaning with ARIA
We also have the math role from the ARIA specification. With that, we can communicate the mathematical semantics even when we rely on images or non-semantic HTML. However, it does not give good results with VoiceOver on macOS, for example.
As shown on the MDN page for the math role, we could have:
<div role="math" aria-label="a^{2} + b^{2} = c^{2}">
a<sup>2</sup> + b<sup>2</sup> = c<sup>2</sup>
</div>Markup with a div with the math role and how screen readers interpret it
Markup
NVDA + Firefox (Windows with MathCAT add-on)
just announces the textVoiceOver + Safari (Mac)
not read, just announces "with 6 items, maths"VoiceOver + Safari (iOS)
a caret left curly bracket 2 right curly bracket plus b caret left curly bracket 2 right curly bracket equals c caret left curly bracket, Math<img src="pythagorean_theorem.png" alt="a^{2} + b^{2} = c^{2}" role="math" />Markup with a img with the math role and how screen readers interpret it
Markup

NVDA + Firefox (Windows with MathCAT add-on)
just announces the textVoiceOver + Safari (Mac)
not read, just announces "maths"VoiceOver + Safari (iOS)
a caret left curly bracket 2 right curly bracket plus b caret left curly bracket 2 right curly bracket equals c caret left curly bracket, MathIn practice, using the math role helps assistive technologies understand that the content is mathematical, but it still doesn’t provide enough semantic detail for them to announce the expression as accurately as MathML does.
The future of MathML
TL;DR: MathML Core is what browsers implement today; MathML 4 is the broader language evolving around it.
As I mentioned at the beginning, the origin of MathML was not the web, it was more of a general-purpose specification for browsers, office suites, computer algebra systems, EPUB readers, and LaTeX-based generators, as stated in Mozilla. MathML Core arose from the need to make it work with web standards, including HTML, CSS, DOM, and JavaScript. Historically, the full MathML spec was broad and partly underspecified for browsers, which led to uneven or incomplete implementations across engines. MathML Core therefore narrows the language to the subset that can be precisely defined on top of the Web Platform, improving testability and cross-browser interoperability. Since June 2025, MathML Core has been a Candidate Recommendation Snapshot. On another note, at the time of this writing, there is a Working Draft for MathML 4, the next version of MathML. This version aims to be the next "full" spec that extends Core. It keeps the larger feature set (e.g., Content MathML) and adds, among others, the intent attribute so authors can guide screen-reader speech. With it, we'll be able to do something like this:
<math>
<mrow intent="equals(power(a,2)+power(b,2),power(c,2))">
<msup>
<mi>a</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<msup>
<mi>b</mi>
<mn>2</mn>
</msup>
<mo>=</mo>
<msup>
<mi>c</mi>
<mn>2</mn>
</msup>
</mrow>
</math>Conclusion
As browser support for MathML continues to evolve, previous fallback solutions like mathml.css are no longer necessary. MathML Core, and soon MathML 4, allow us to express both the visual and semantic meaning of mathematical content without sacrificing accessibility along the way.
Screen-reader support is also steadily improving. Each assistive technology handles MathML in its own way, but the overall trajectory is positive. VoiceOver offers consistent navigation and speech for many common patterns across macOS and iOS. JAWS, especially when paired with Fusion, provides rich support for both speech and braille. And NVDA, which historically required an add-on, is now moving toward a built-in MathCAT integration, making MathML speech and braille support more accessible out of the box for Windows users.
About Manuel Sánchez
Accessibility specialist and game developer at DIE ZEIT. Currently creating The Runic Edda, a solo game blending storytelling, Viking history, and fun. I am driven by curiosity, creativity, and the belief that technology should welcome everyone.
Web: manuelsanchezdev.com
Bluesky: @manuelsanchezdev.com
Comments
There are no comments yet.
Leave a comment