Static Math Formulas
Converting LaTeX to Various Formats
The mathfield library includes some utility functions to convert between various formats. These utility functions can be used without a mathfield. In fact, they do not require a browser environment at all, and can be used in a Node.js environment.
They are available as a Service Side Render (SSR) package which can be imported as follows:
import * from 'mathlive/ssr';
To convert LaTeX to HTML, use the
convertLatexToMarkup() function.
import { convertLatexToMarkup } from 'mathlive';
console.log(convertLatexToMarkup('x^2 + y^2 = z^2'));
To convert LaTeX to MathML, use the
latexToMathML() function.
import { convertLatexToMathMl } from 'mathlive';
console.log(convertLatexToMathMl('x^2 + y^2 = z^2'));
To convert LaTeX to spoken text, use the
convertLatexToSpeakableText()
function.
import { convertLatexToSpeakableText } from 'mathlive';
console.log(convertLatexToSpeakableText('x^2 + y^2 = z^2'));
To convert LaTeX to AsciiMath, use the
convertLatexToAsciiMath()
function.
import { convertLatexToAsciiMath } from 'mathlive';
console.log(convertLatexToAsciiMath('x^2 + y^2 = z^2'));
Converting From Various Formats to LaTeX
To convert MathJson to LaTeX, use the
convertMathJsonToLatex() function.
import { convertMathJsonToLatex } from 'mathlive';
console.log(convertMathJsonToLatex(["Add", "x", "y"]));
To convert AsciiMath to LaTeX, use the
convertAsciiMathToLatex()
function.
import { asciiMathToLatex } from 'mathlive';
console.log(convertAsciiMathToLatex('x^2 + y^2 = z^2'));
Rendering Static Math Formulas
MathLive provides two approaches for rendering static (non-editable) math formulas:
- Web Components (
<math-span>and<math-div>) - A simple, declarative approach using custom HTML elements - Auto-rendering (
renderMathInDocument()) - Automatically converts LaTeX delimiters in your document to rendered math
Using Web Components
For simple static formulas, use the <math-span> and <math-div> web
components. These provide a lightweight way to render math without editing
capabilities.
<!-- Inline formula -->
<p>The famous equation <math-span>E = mc^2</math-span> was discovered by Einstein.</p>
<!-- Block formula -->
<math-div>\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}</math-div>
Attributes:
mode: Set totextstyle(default for<math-span>) ordisplaystyle(default for<math-div>)format: Set tolatex(default),ascii-math, ormath-jsonletter-shape-style: Set toauto,tex,iso,french, oruprightmacros: JSON string of custom LaTeX macrosmin-font-scale: Minimum font scalingmax-matrix-cols: Maximum matrix columnsaria-label: Custom accessible description (auto-generated if not provided)tabindex: Set to0to make formula focusable and enable keyboard navigationrole: Automatically set toimg(can be overridden)
Examples:
<!-- AsciiMath format -->
<math-span format="ascii-math">x^2 + y^2</math-span>
<!-- MathJSON format -->
<math-div format="math-json">["Add", "x", "y"]</math-div>
<!-- Override display mode -->
<math-span mode="displaystyle">\sum_{i=1}^n i^2</math-span>
<!-- Custom letter shape style -->
<math-div letter-shape-style="iso">f(x) = ax + b</math-div>
<!-- Programmatic rendering -->
<math-div id="formula">x + y</math-div>
<script type="module">
const formula = document.getElementById('formula');
formula.textContent = 'x^2 + y^2 = z^2';
formula.render(); // Manually trigger re-render
</script>
Events:
render: Fired when content is successfully renderedrender-error: Fired when rendering fails
const mathDiv = document.querySelector('math-div');
mathDiv.addEventListener('render', (event) => {
console.log('Rendered:', event.detail.content);
});
mathDiv.addEventListener('render-error', (event) => {
console.error('Render error:', event.detail.error);
});
Performance Features:
The components include built-in performance optimizations:
- Lazy Font Loading: Fonts are loaded once globally across all components, reducing network requests
- Intersection Observer: Off-screen formulas are rendered only when they become visible (50px before entering viewport), dramatically improving page load times for documents with many formulas
Accessibility Features:
The components are designed with accessibility in mind:
- Auto-generated ARIA Labels: Formulas automatically receive
aria-labelattributes with speakable text descriptions (user-provided labels take precedence) - MathML Fallback: Hidden MathML is included for screen readers that support it
- Keyboard Navigation: When made focusable with
tabindex="0", formulas can be navigated with Tab and activated with Space/Enter to hear the description via speech synthesis - Semantic Role: Automatically set to
role="img"for proper accessibility tree representation
<!-- Auto-generated accessibility -->
<math-span>E = mc^2</math-span>
<!-- Custom ARIA label (preserved) -->
<math-span aria-label="Einstein's mass-energy equivalence">E = mc^2</math-span>
<!-- Keyboard navigable -->
<math-div tabindex="0">\int_0^1 f(x) dx</math-div>
Auto-rendering with renderMathInDocument()
To render math contained in a document as a static (non-editable) formula,
call renderMathInDocument() at the
end of your document, or in a DOMContentLoaded event handler.
<script defer type="module">
window.addEventListener('DOMContentLoaded', () =>
import('https://esm.run/mathlive').then((mathlive) =>
mathlive.renderMathInDocument()
)
);
</script>
By default, any LaTeX code in the text element of a DOM element that is enclosed with the following delimiters will be rendered as math:
\[...\]or$$...$$-- rendered in Display Style (CSS display block)\(...\)-- rendered in Text Style (CSS display inline)
<h1>Taxicab Number</h1>
<p>The second taxicab number
is \\(1729 = 10^3 + 9^3 = 12^3 + 1^3\\)
</p>
More complex expressions can be wrapped in a <script> tag. One of the benefits
of this approach is that the browser will not attempt to display the content of
the <script> tag before it is typeset, avoiding an unsightly flash of code on
screen.
To render LaTeX code, use <script type="math/tex">
To render MathJSON, use <script type="math/json">
To render the formula inline, append ; mode=text to the type. If no
mode is provided, or mode=display, the display (block) style is used.
<h1>Quadratic roots</h1>
<script type="math/json"> ["Add",
["Multiply", "a", ["Square", "x"]]],
["Multiply", "b", "x"],
"c"
]
</script>
<script type="math/tex; mode=text">
= a
\left( x - \frac{-b + \sqrt {b^2-4ac}}{2a} \right)
\left( x - \frac{-b - \sqrt {b^2-4ac}}{2a} \right)
</script>
The following DOM elements are ignored for conversion: <noscript>, <style>,
<textarea>, <pre>, <code>, <annotation> and <annotation-xml>.
If you dynamically generate content, call
renderMathInElement(element) to
render your element after the page has been loaded. This is a recursive call
that will be applied to element and all its children.
To render again elements or a whole document that has already been rendered,
call renderMathInElement() and renderMathInDocument() again. This is useful
when a change in the environment requires the layout to be updated.
To customize the behavior of the renderMathInElement() and
renderMathInDocument() functions pass an optional options object literal:
skipTags: an array of tag names whose content will not be scanned for delimitersprocessScriptType:<script>tags of the indicated type will be processed while others will be ignored. Default: "math/tex".ignoreClass: a string used as a regular expression of class names of elements whose content will not be scanned for delimiters ("tex2jax_ignore"by default)processClass: a string used as a regular expression of class names of elements whose content will be scanned for delimiters, even if their tag name or parent class name would have prevented them from doing so. ("tex2jax_process"by default)TeX.processEnvironments: if false, math expression that start with\begin{will not automatically be rendered. (true by default)TeX.delimiters.inlineandTeX.delimiters.displayarrays of delimiters that will trigger a render of the content in 'textstyle' or 'displaystyle' style, respectively.
renderMathInElement(document.getElementById('formulas'), {
// Elements with a class of "instruction" or "source"
// will be skipped
ignoreClass: 'instruction|source',
TeX: {
delimiters: {
// Allow math formulas surrounded by $...$ or \(...\)
// to be rendered as inline (textstyle) content.
inline: [
['$', '$'],
['\\(', '\\)'],
],
display: [],
},
},
});
Choosing Between Web Components and Auto-rendering
Use <math-span> and <math-div> when:
- You want a simple, declarative API
- You need to render individual formulas
- You want programmatic control over re-rendering with the
render()method - You need to handle render events
- You're working with dynamic content that changes frequently
- You want to use different input formats (LaTeX, AsciiMath, or MathJSON)
Use renderMathInDocument() when:
- You have existing content with LaTeX delimiters (
\(...\),$$...$$, etc.) - You want to convert an entire document at once
- You're migrating from other LaTeX rendering libraries (like KaTeX or MathJax)
- You need to render math in
<script type="math/tex">tags
Both approaches produce the same visual output and share the same rendering engine. The main difference is in how you specify and control the rendering.
Read-only Mathfield
When a math formula is displayed as a static element using
renderMathInDocument(), the formula is transformed into some static markup. As
a result, only the markup content can be selected, not the underlying LaTeX
formula. Selection of a portion of the formula may also lead to unexpected
results.
If preserving the ability to select a formula is important, consider using a read-only mathfield instead.
To create a read-only mathfield, add the read-only attribute to a
<math-field> element.