MathJax icon indicating copy to clipboard operation
MathJax copied to clipboard

Determining when line breaks should occur on small screens in 4.0.0 with firefox.

Open somiaj opened this issue 3 months ago • 13 comments

In testing if some of my formulas are more responsive using the line break feature of 4.0.0, I have determined that sometimes line breaks occur on smaller screens and other times they don't. I haven't figured out the logic here and if it is something that I can improve or configure.

I have an equal chain that doesn't line break on smaller screens.

\(A\vec{\bf x} =
 \begin{bmatrix} 2 & 2 \\ -1 & 3\end{bmatrix}
 \begin{bmatrix} 2 \\ 3\end{bmatrix}
 = \begin{bmatrix} (2)(2) + (2)(3) \\ (-1)(2) + (3)(3) \end{bmatrix}
 = \begin{bmatrix} 10 \\ 7 \end{bmatrix}\)

But if I add another matrix to the equal chain it does line break.

\(A\vec{\bf x} =
 \begin{bmatrix} 2 & 2 \\ -1 & 3\end{bmatrix}
 \begin{bmatrix} 2 \\ 3\end{bmatrix}
 = \begin{bmatrix} (2)(2) + (2)(3) \\ (-1)(2) + (3)(3) \end{bmatrix}
 = \begin{bmatrix} 4 + 6 \\ -2 + 9 \end{bmatrix}
 = \begin{bmatrix} 10 \\ 7 \end{bmatrix}\)

Here is a screenshot, the first equal chain the last matrix is pushed off the edge of the screen, while the second causes a line break.

Image

In trying to determine what causes the line breaks, it seems to be the number of matrices, and not their sizes. For example if I make the last matrix bigger in the first example by writing the numbers as a sum of 1's:

\(A\vec{\bf x} =
 \begin{bmatrix} 2 & 2 \\ -1 & 3\end{bmatrix}
 \begin{bmatrix} 2 \\ 3\end{bmatrix}
 = \begin{bmatrix} (2)(2) + (2)(3) \\ (-1)(2) + (3)(3) \end{bmatrix}
 = \begin{bmatrix} 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1\\ 1 + 1 + 1 + 1 + 1 + 1 + 1 \end{bmatrix}\)

No line break occurs just like the first example, even though this statement is now longer than the second example which has a line break in it.

I did notice there have been various issues and some fixes with line breaks in 4.0.0, but I could not determine if this was addressed (this particular issue didn't seem to be included in the other issue and fixes I saw, and I didn't have time to test if this was fixed by building the most recent mathjax from source).

somiaj avatar Nov 15 '25 18:11 somiaj

A little more investigating, it does line break as expected on a smaller phone, it was only when testing it on my browser in a narrow window. I think the issue might also be related to I use a larger DPI on my desktop than default, and this maybe why MathJax is not computing the break points to line break as it might not be taking in the DPI (or maybe zoom) of my browser.

somiaj avatar Nov 16 '25 16:11 somiaj

In-line breaks are actually handled by the browser. MathJax marks potential breakpoints using spaces so that the browser can break at them, but not all browsers handle this equally well. In particular, Firefox doesn't like to break at the last potential breakpoint (in your case, the final equal sign). Are you testing in Firefox? If you add = X at the end of the expression does that then break for you?

I don't think the DPI makes a difference. MathJax makes every top-level equal sign a potential breakpoint. If you view the DOM, you should see mjx-break elements at all the potential break points. If the browser isn't breaking at one of those, that may be a browser bug.

What browser and OS are you using?

dpvc avatar Nov 16 '25 18:11 dpvc

Yes, I am using firefox. Didn't realize that this could be a browser issue, I'll do some more testing with other browsers and as you suggest add the =X to see if that gets firefox to want to wrap.

somiaj avatar Nov 16 '25 18:11 somiaj

I have been doing a little more testing with Firefox, and if there is any text before the inline expression, then the wrapping occurs for me. I'm experimenting with adding U+200B or U+200B (zero width spaces) before the inline expression to see if that can overcome the problem.

dpvc avatar Nov 16 '25 19:11 dpvc

Here is a configuration that might resolve the issue for you.

MathJax = {
  options: {
    renderActions: {
      linebreaks: [210,
        (doc) => {for (const math of doc.math) MathJax.config.addZeroWidthSpace(math, doc)},
        (math, doc) => MathJax.config.addZeroWidthSpace(math, doc)
      ],
    },
  },
  addZeroWidthSpace(math, doc) {
    if (math.display || math.outputData.hasZeroWidthSpace) return;
    const prev = math.typesetRoot.previousSibling;
    if (prev?.nodeName === '#text' && prev.textContent.endsWith('\u200C')) return;
    const adaptor = doc.adaptor;
    adaptor.insert(adaptor.text('\u200C'), math.typesetRoot);
    math.outputData.hasZeroWidthSpace = true;
  }
};

This inserts U+200C before any inline expression, which seems to be enough to allow Firefox to use the final breakpoint. See how that works for you, and let us know the result, please.

dpvc avatar Nov 16 '25 19:11 dpvc

Thanks for looking into this, but might it be something that should be reported to firefox?

somiaj avatar Nov 16 '25 19:11 somiaj

might it be something that should be reported to firefox?

Probably, but it's not something I tend to do.

dpvc avatar Nov 16 '25 19:11 dpvc

@dpvc I can confirm that with your suggested configuration, line breaks work more like I expect them to in firefox-esr.

somiaj avatar Nov 16 '25 19:11 somiaj

The situation is a bit complicated, because MathJax's mjx-container element has white-space: nowrap set, and the mjx-break elements have white-space: normal, and it may well be that the the interplay between these white-space settings is the source of the problem in Firefox. This setup helps prevent punctuation that follows an inline expression from breaking onto the next line. But it might be possible to handle that differently (e.g., by wrapping the pieces between breaks in a separate container that has white-space: nowrap instead).

dpvc avatar Nov 16 '25 19:11 dpvc

I can confirm that with your suggested configuration, line breaks work more like I expect them

Thanks for the test results.

dpvc avatar Nov 16 '25 19:11 dpvc

I have a tangential issue I will add here (unless you prefer I open another issue). This fix didn't cause display="true" formulas to wrap (for obvious reasons), so I was trying to find a way to better deal with overflowing formulas in this case. I thought adding a scroll bar would do the trick so just the formula scrolls vs the whole page, so I added the following css

mjx-container[display="true"] { overflow-x: auto; }

This mostly works except it turns out that it is not possible to have overflow-x: auto and overflow-y: visible, in this case the visible also becomes auto and for some reason all the display="true" formulas are slightly taller than their containing div so now I get a tiny amount of vertical scroll in all my display="true" formulas.

Image

This even includes formulas that have no overflow in the horizontal direction, in those case I can jiggle the formula up and down but not right and left.

somiaj avatar Dec 07 '25 15:12 somiaj

You don't need to add this CSS yourself, as MathJax has a setting that allows you to specify that wide expressions should scroll. You can try this out using the MathJax contextual menu's "Math Settings -> Wide Expressions -> Scroll" setting. If you like that, you can configure MathJax to make that the default using

MathJax = {
  output: {
    displayOverflow: 'scroll',
  }
};

You are correct that when one of the overflow CSS options to auto, the other can't be visible. This is because when overflow is set to other than visible (or clip), the element creates a new scroll region, and for overflow in the other direction, visible is converted to auto. (Scrolling is restricted to the padding region of the element, so if overflow were visible, it wouldn't scroll with the rest of the content.) See the MDN documentation on this, particularly the "Description" section.

dpvc avatar Dec 07 '25 18:12 dpvc

Thanks, and seems using that vs raw css makes the vertical scrolling issue go away, I just didn't see how to adjust the configuration (And forgot to look at the menu). I'll have to dig deeper into the docs. Thanks @dpvc.

somiaj avatar Dec 07 '25 18:12 somiaj