Skip to content

Issues with MathJax 4 in RTL settings: SVG had serious ordering issue, and CHTML is not rendering in an overall LTR manner as expected #3589

Description

@taniwallach

Issue Summary

When using MathJax v4 in Chrome/Ubuntu 22.04, math content rendered by MathJax in a HTML document in a RTL (right-to-left) direction is not rendering properly in a Hebrew paragraph, nor consistently in CHTML and SVG modes. I suspect the issue applies to other RTL languages. (Sample also shows it occurring for Persian.)

In CHTML mode, essentially the "pieces" of an expression are appearing from right-to-left, which is not the accepted practice for math in Hebrew text, where the "blocks" of math (each MathJax expression) would be expected to render LTR (unless there was some inline Hebrew, where it would be nice for the Hebrew words to render RTL).

In SVG mode - the situation is worse. An \( a \ne 0 \) rendered with both the a and the 0 on the same side of the equals sign.

It seems that MathJax v4 is trying to pick up the "correct" direction based on the surrounding text, as when the inline math inside an RTL document is inside an English paragraph - it does render as expected.

The issue can be overcome by enclosing the math expression inside an span setting dir="ltr".

Note: With v3, the CSS setting of direction: ltr on mjx-container was made in mathjax/MathJax-src#349 and had things working well for SVG mode. That CSS setting still exists, but does not seem to have an effect.

Steps to Reproduce:

  1. Save the HTML file test03-svg.html attached below or copy the text at the very bottom to a local HTML file.
  2. Render in a browser.
  3. Pay attention to how the two inline math expressions appear in the 3 paragraphs in the top section (default MathJax in SVG mode).
  4. Compare to how it is rendered in the bottom 2 paragraphs below the horizontal line.
  5. Repeat for test03-chtml.html attached below, or change the 'srcline in the file to usetex-mml-chtml.js(and the headers to haveSVGinstead ofCHTML`) and examine the output.

The expected behavior would be for the inline equations to all render the same manner, as results when the explicit RTL span is added in the last 2 paragraphs.

Technical details:

  • MathJax Version: 4.1.3
  • Client OS: Ubuntu 22.04
  • Browser: Firefox 152.0.4 (64-bit), and Chrome 150.0.7871.46 (Official Build) (64-bit)

The example loaded MathJax via

  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-svg.js">
  </script>

and

  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js">
  </script>

Supporting information:

HTML files:

Note: The third and fifth example use some Persian word to trigger the same issue as in the Hebrew examples (first and fourth). I just copied that word from the example in #2204 to see the behavior in a different RTL language. That sentence tested is just gibberish to me.


Images of the rendered pages:

Image Image Image Image Image Image

The HTML file for the SVG case is below:

<!DOCTYPE html>
<html lang="he_IL" dir="rtl">
<head>
  <meta charset="utf-8">
  <title>MathJax example</title>
  <script id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-svg.js">
  </script>
</head>
<body>
<h2 dir="ltr"><strong>Default MathJax v4 (SVG)</strong></h2>
<p>
  כאשר \(a \ne 0\), יש 2 פתרונות למשוואה \(ax^2 + bx + c = 0\) והם
  \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
</p>
<p>
  When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
  \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
</p>
<p>
  داریم \(a \ne 0\), داریم \(ax^2 + bx + c = 0\) داریم
  \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
</p>
<hr>
<h2 dir="ltr"><strong>Explicit LTR spans added below (SVG)</strong></h2>
<p>
כאשר <span dir="ltr">\(a \ne 0\)</span>, יש 2 פתרונות למשוואה <span dir="ltr">\(ax^2 + bx + c = 0\)</span> והם
  \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
</p>
<p>
  ﺩﺍﺮﯿﻣ <span dir="ltr">\(a \ne 0\)</span>,
  ﺩﺍﺮﯿﻣ <span dir="ltr">\(ax^2 + bx + c = 0\)</span>
  ﺩﺍﺮﯿﻣ
  \[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
</p>
</body>
</html>

Activity

  1. dpvc commented on Jul 9, 2026

    @dpvc
    Member

    Thanks for the report. It looks like the direction CSS is not sufficient by itself to override the direction from the text in which the math appears. Adding unicode-bidi: isolate seems to do the trick, however, so a work-around for now would be to add

    mjx-container {
      direction: ltr;
      unicode-bidi: isolate;
    }

    to the page's CSS.

    The other approach is to have MathJax add dir="ltr" attributes to the mjx-container elements, which is, apparently, preferred to setting direction in CSS.

    Here is a configuration that adds the dir attribute:

    MathJax = {
      loader: {
        'output/chtml': {
          ready() {
            const {CHTML} = MathJax._.output.chtml_ts;
            Object.assign(CHTML.prototype, {
              _createNode_: CHTML.prototype.createNode,
              createNode() {
                const node = this._createNode_();
                this.adaptor.setAttribute(node, 'dir', 'ltr');
                return node;
              }
            });
          }
        },
        'output/svg': {
          ready() {
            const {SVG} = MathJax._.output.svg_ts;
            Object.assign(SVG.prototype, {
              _createNode_: SVG.prototype.createNode,
              createNode() {
                const node = this._createNode_();
                this.adaptor.setAttribute(node, 'dir', 'ltr');
                return node;
              }
            });
          }
        },
      },
    };

    It will work for both CHTML and SVG output (and will handle the situation where the user selects the other renderer via the MathJax contextual menu).

    I will make a PR to fix that in the next release.

  2. added
    AcceptedIssue has been reproduced by MathJax team
    Code ExampleContains an illustrative code example, solution, or work-around
    on Jul 9, 2026
  3. taniwallach commented on Jul 12, 2026

    @taniwallach
    Author

    @dpvc Thanks for finding a fix and making the PR with a patch so quickly!
    I confirm that adding the configuration suggested above solves the problem in both tested browsers, and is expected to work everywhere.

  4. dpvc commented on Jul 12, 2026

    @dpvc
    Member

    Thanks for testing this out and letting us know the result.

  5. added this to the v4.2 milestone on Jul 12, 2026
  6. added a commit that references this issue on Jul 17, 2026
  7. added
    MergedMerged into develop branch
    and removed on Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    AcceptedIssue has been reproduced by MathJax teamCode ExampleContains an illustrative code example, solution, or work-aroundMergedMerged into develop branchv3v4

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions