Making MathJax Math Formulas Automatically Scale with Window Size

By 苏剑林 | October 15, 2024

With the emergence and popularity of MathJax, displaying mathematical formulas on web pages has gradually become the standard solution. However, MathJax (including its competitor KaTeX) is only responsible for converting web LaTeX code into mathematical formulas; it still lacks a robust method for adaptive resolution. Like some of the mathematical articles on this site, because they were composed on a PC, the browsing effect is acceptable on the PC side, but it can become somewhat unsightly when viewed on a mobile phone.

After some testing, I have developed a solution that allows MathJax mathematical formulas to automatically scale with the window size, just like images, thereby ensuring the best possible display effect on mobile devices. I would like to share this with you all.

Background Idea

The origin of this problem is that even when composing on a PC, there are times when the length of a single-line formula exceeds the width of the webpage, but it is not convenient to break the line. In such cases, one solution is to manually adjust the font size of the formula using HTML code, for example:

<div style="font-size: 90%"> 
 \begin{equation}A very long mathematical formula\end{equation}
</div>

This adjusts the size of the mathematical formula to 90% of the original. While this solves most problems, manual adjustment is ultimately a bit troublesome. The figure of 90% needs to be manually debugged several times to obtain the optimal value, and it can only adapt to a single width. A few days ago, I suddenly realized a question: Why can't mathematical formulas be set with a max-width to automatically scale in size like images? For example, the following image code:

<img src="example.png" style="max-width: 100%; width: 400px;" />

The effect achieved is that the image size stays as close to 400px as possible without exceeding the parent element. After some testing, I found that MathJax mathematical formulas are text blocks and there is no ready-made method to achieve the max-width scaling characteristic of images. However, we can use JavaScript to calculate the ratio by which a formula exceeds the width of its parent element and then automatically set the font-size for the mathematical formula to achieve the same effect.

Code Reference

First, here is the final reference solution. Replace the original MathJax configuration code with the following:

 MathJax.Hub.Config({
 tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]},
 TeX: {equationNumbers: {autoNumber: ["AMS"], useLabelIds: true}, extensions: ["AMSmath.js", "AMSsymbols.js", "extpfeil.js"]},
 "HTML-CSS": {noReflows: false, availableFonts: ["tex"], styles: {".MathJax_Display": {margin: "1em 0em 0.7em;", display: "inline-block!important;"}}},
 "CommonHTML": {noReflows: false, availableFonts: ["tex"], styles: {".MJXc-display": {margin: "1em 0em 0.7em;", display: "inline-block!important;"}}},
 "SVG": {noReflows: false, availableFonts: ["tex"], styles: {".MathJax_SVG_Display": {margin: "1em 0em 0.7em;", display: "inline-block!important;"}}}
 });
 MathJax.Hub.Queue(function() {
 document.querySelectorAll('span[id^="MathJax-Element"]').forEach(function(e) {
 parentWidth = e.parentNode.offsetWidth;
 if (e.parentNode.className.endsWith('isplay')) {
 parentWidth = e.parentNode.parentNode.offsetWidth;
 }
 if (e.offsetWidth > parentWidth) {
 e.style.fontSize = parentWidth * 100 / e.offsetWidth + '%';
 }
 });
 });

Compared to the configuration code mentioned in "Making MathJax Better Compatible with Google Translate and Lazy Loading", there are two key changes. First, the configuration item {linebreaks: {automatic: true, width: "95% container"} has been removed. The purpose of this configuration was to enable automatic line breaking, originally intended to improve adaptability to resolution. However, in practice, it is not very useful; many well-written mathematical formulas actually look worse if they are broken automatically. Therefore, removing automatic line breaks ensures the consistency of mathematical formulas across different widths.

The next key modification is the MathJax.Hub.Queue section. This is a function executed after formula rendering is complete. It first finds all span elements with an ID starting with "MathJax-Element," which are all the mathematical formulas. Then, it obtains its width through e.offsetWidth and the width of its parent element via e.parentNode.offsetWidth or e.parentNode.parentNode.offsetWidth. Based on this result, it calculates and sets the percentage by which the font-size should be reduced.

When should e.parentNode.offsetWidth or e.parentNode.parentNode.offsetWidth be used? Mathematical formulas are divided into "inline formulas" and "display formulas." Inline formulas use the former directly, while display formulas use the latter. In the code, display formulas are nested within an extra layer of div, so the grandparent node is the parent element. Since the class of this div ends with "Display" or "display," the criterion e.parentNode.className.endsWith('isplay') was added.

The above explains all the principles of the reference code.

Summary

This article shares a solution for making MathJax formulas automatically scale according to the window size, which can be as compatible as possible with the narrow-screen browsing requirements of mobile devices. After adjustment, even on a small screen, mathematical formulas will appear the same as they do on a PC—though they might be a bit straining for the eyes, it is a useful emergency measure.

Modified narrow-screen display effect