Skip to main content

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:

  1. Web Components (<math-span> and <math-div>) - A simple, declarative approach using custom HTML elements
  2. 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 to textstyle (default for <math-span>) or displaystyle (default for <math-div>)
  • format: Set to latex (default), ascii-math, or math-json
  • letter-shape-style: Set to auto, tex, iso, french, or upright
  • macros: JSON string of custom LaTeX macros
  • min-font-scale: Minimum font scaling
  • max-matrix-cols: Maximum matrix columns
  • aria-label: Custom accessible description (auto-generated if not provided)
  • tabindex: Set to 0 to make formula focusable and enable keyboard navigation
  • role: Automatically set to img (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 rendered
  • render-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-label attributes 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 delimiters
  • processScriptType: <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.inline and TeX.delimiters.display arrays 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.

<style> math-field[read-only] { border: none; background-color: transparent; } </style> <p>The solution of the equation is <math-field read-only style="display:inline-block"> x=\frac{-b\pm \sqrt{b^2-4ac}}{2a} </math-field> </p>