<ul>, <img>, and <p> in mathtip

38 views
Skip to first unread message

Andrew Murdza

unread,
Oct 15, 2025, 11:53:49 AMOct 15
to MathJax Users
I want to use <ul><li>  … </li></ul>, <img> and <p>  … </p> inside of MathJax tooltips. I was using an aligned environment with &\bullet, but I want it to be regular html so that I don’t have to use \text{  … } and there are automatic line breaks. I’m wondering if it can be done in MathJaxv4.0, or if it only works for in-line elements like <span>...</span>.

Davide Cervone

unread,
Oct 16, 2025, 6:20:56 AMOct 16
to mathja...@googlegroups.com
In MathJax v4, you can use the texhtml extension to enter HTML tags within a \mathtip.  For example, with this extension, you can do

$$x = \mathtip{y}{{<tex-html><img src="https://freetestdata.com/wp-content/uploads/2025/03/cropped-F-T-D-3.png"></tex-html>}}$$

would produce a tooltip containing an image:

ToolTip-img.png
(The double braces in the tip are important, here, so that it looks like mathematics rather than just text to MathJax.)

But you have to be careful about where the math is, as block-level tags may cause the surrounding tags to close unexpectedly, and then MathJax may not be able to identify the math correctly.  For example, if you have something like

<p>
Some text
<ul>
  <li>item 1</li>
  <li>item 2</li>
</ul>
other text
</p>

then the browser will interpret that as 

<p>Some text</p>
<ul>
  <li>item 1</li>
  <li>item 2</li>
</ul>
other text
<p></p>

So if you had 

<p>
Some text $x = \mathtip{y}{{
<tex-html>
  <div style="width: 5em">
    <ul>
      <li>item 1</li>
      <li>item 2</li>
    </ul>
  </div>
</tex-html>}}$
other text
</p>

the browser would first rewrite this as

<p>
Some text $x = \mathtip{y}{{
<tex-html>
</tex-html>
</p>
  <div style="width: 5em">
    <ul>
      <li>item 1</li>
      <li>item 2</li>
    </ul>
  </div>
}}$ other text
<p></p>

and the dollar sign in the first paragraph will not have a matching end dollar sign within that paragraph, and so MathJax will not consider it to be a proper math delimiter and won't process the math.

That means you have to be careful about using block-level HTML within <tex-html> tags.  If the math is inside a tag that allows internal block-level tags (like <div> for example), then that will be fine, but if the math is inside a tag (like <p>) that doesn't then it will cause problems.

So you could do

<div>
Some text $x = \mathtip{y}{{
<tex-html>
  <div style="width: 5em">
    <ul>
      <li>item 1</li>
      <li>item 2</li>
    </ul>
  </div>
</tex-html>}}$
other text
</div>

but you could not use <p> instead of <div> here.

If you want to be able to use lists and other block-level elements inside a <p> tag, there is a possible solution, which is to use custom tags that perform the same layout.  For example, you could use

<p>
Some text $x = \mathtip{y}{{
<tex-html>
  <x-div>
    <x-ul>
      <x-li>item 1</x-li>
      <x-li>item 2</x-li>
    </x-ul>
  </x-div>
</tex-html>}}$
other text
</p>

and then us CSS to style the "x-" tags as necessary.  For example:

<style>
x-div {
  display: block;
  width: 5em;
}
x-ul {
  display: list;
}
x-li {
  display: list-item;
  margin-left: 1em;
}
</style>

would make these like div, ul, and li elements.

Here is a complete file that illustrates the two approaches:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>2110 - \input command</title>
<script>
MathJax = {
  loader: {
    load: ['[tex]/texhtml', '[tex]/action'],
  },
  tex: {
    packages: {'[+]': ['texhtml', 'action']},
    allowTexHTML: true,
  },
};
</script>
<style>
x-div {
  display: block;
  width: 5em;
}
x-ul {
  display: list;
}
x-li {
  display: list-item;
  margin-left: 1em;
}
div.tooltip {
  width: 5em;
}
div.tooltip ul {
  margin: 0;
  padding: 0;
}
div.tooltip li {
  margin-left: 1em;
}
</style>
</head>
<body>

<p>
A test in a paragraph
\(x = \mathtip{y}{{
  <tex-html>
  <x-div>
    <x-ul>
      <x-li>first line</x-li>
      <x-li>second line</x-li>
    </x-ul>
  </x-div>
  </tex-html>
}}\) that has math tip with a list.
</p>

<div>
A test in a div
\(x = \mathtip{y}{{
  <tex-html>
  <div class="tooltip">
    <ul>
      <li>first line</li>
      <li>second line</li>
    </ul>
  </div>
  </tex-html>
}}\) that has a math tip with a list.
</div>

</body>
</html>

The output for the first math-tip is

ToolTip-1.png
and the second is

ToolTip-2.png
Note that the browser is breaking the second list item automatically (like you asked for) at the 5em mark that is set in the CSS.

So you can do this sort of thing, if you are careful.

Davide



On Oct 15, 2025, at 11:53 AM, Andrew Murdza <andrew...@gmail.com> wrote:

I want to use <ul><li>  … </li></ul>, <img> and <p>  … </p> inside of MathJax tooltips. I was using an aligned environment with &\bullet, but I want it to be regular html so that I don’t have to use \text{  … } and there are automatic line breaks. I’m wondering if it can be done in MathJaxv4.0, or if it only works for in-line elements like <span>...</span>.

--
You received this message because you are subscribed to the Google Groups "MathJax Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mathjax-users/23688989-b89d-433d-8f93-a4bd2f430302n%40googlegroups.com.

Andrew Murdza

unread,
Oct 18, 2025, 3:54:58 PMOct 18
to MathJax Users
<x-li> is exactly what I wanted!

Is there a way to set it so that I can do \mathtipNew{#1}{#2}{#3} and it makes \mathtip{#1}{#2}, but the width of the tooltip is the maximum of #1 and 1.2* the width of #2? I tried using <div data-mjx-hdw="4em 4em 4em"> \mathtip{y}{{tex-html>
    <div class="tooltip" data-mjx-hdw="16em 16em 16em" style="width: 400px;">... and <div style='min-width:500px;"> \mathtip{y}{{tex-html>
    <div class="tooltip" data-mjx-hdw="4em 4em 4em" style="width: 400px;">... and neither of them changed the width. I also want it to be the maximum of #1 and 1.2*the width of #2, not just the width of #1.

Andrew Murdza

unread,
Oct 18, 2025, 6:13:04 PMOct 18
to MathJax Users
Never mind, I was using 'min-width' on the wrong line. This works:
<p>
A test in a paragraph
\(x = \mathtip{y}{{
<tex-html>
<x-div style="min-width:500px;">
<x-ul>
<x-li>first line</x-li>
<x-li>second line</x-li>
</x-ul>
</x-div>
</tex-html>
}}\) that has math tip with a list.
</p>
<p>
A test in a paragraph
\(x = \mathtip{y}{{
<tex-html>
<x-div class="math-tip" "data-minWidth="80px">
<x-ul>
<x-li>first line</x-li>
<x-li>second line</x-li>
</x-ul>
</x-div>
</tex-html>
}}\) that has math tip with a list.
</p>

I was able to do it with your code for the \and question and it worked.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Multiple MathJax tooltips</title>
<script>
MathJax = {
loader:{load:['[tex]/texhtml','[tex]/action']},
tex:{
packages:{'[+]':['texhtml','action']},allowTexHTML:true,
macros:{
'mathtipNew':['\\mathtip{\\class{tip-top}{#2}}{{<tex-html><div class="tooltip" data-minWidth="#1">#3</div></tex-html>}}',3]
}
},
startup:{
async pageReady() {
await MathJax.startup.defaultPageReady();
const items = Array.from(MathJax.startup.document.math);
for (const item of items) {
const root = item.typesetRoot;
const tops = root.querySelectorAll('.tip-top');
const tips = root.querySelectorAll('.tooltip');
for (let i = 0; i < Math.min(tops.length, tips.length); i++) {
const top = tops[i], tip = tips[i];
const topWidth = top.getBoundingClientRect().width;
const minWidth = tip.dataset.minwidth;
tip.style.width = `max(calc(1.2 * ${topWidth}px), ${minWidth})`;
}
}
MathJax.typesetPromise();
}
}
};
</script>
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
</head>
<body>
<div>
Example:
\(\mathtipNew{300px}{ABC}{Hello <tex-math>x</tex-math>}\)
</div>
</body>
</html>

The problem now is that \mathtipNew{x^2+1}{Hi \(x=1\)} Shows the \(x=1\) as literally the text "\(x=1\)" (not the equation x=1).

Andrew Murdza

unread,
Oct 19, 2025, 8:16:18 PMOct 19
to MathJax Users
If it helps, I found that the issue with \(x=1\) is not due to the <x-li> or min-width code I added or due to the macro I defined. What is causing the issue is specifically \(x\) inside of <tex-html>. In my above screenshot, I put <tex-math>x</tex-math> because that was one of the things ChatGPT suggested. But I had previously tested it with \(x=1\).

This is a minimal example of the issue:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Multiple MathJax tooltips</title>
<script>
MathJax = {
loader:{load:['[tex]/texhtml','[tex]/action']},
tex:{
packages:{'[+]':['texhtml','action']},allowTexHTML:true
},
};
</script>
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
</head>
<body>
<div>
\(\mathtip{x=1}{{<tex-html>Hi \(x=1\)</tex-html>}}\)
</div>
</body>
</html>

Andrew Murdza

unread,
Oct 19, 2025, 8:23:42 PMOct 19
to MathJax Users
I'm sorry for not mentioning this in the previous message, but this is even more minimal and shows the exact root of the problem: Math cannot be placed inside <tex-html></tex-html>. I don't think that will be easy to fix, unfortunately, but I'm really looking forward to having that feature, especially for my tooltips.

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Multiple MathJax tooltips</title>
<script>
MathJax = {
loader:{load:['[tex]/texhtml']},
tex:{
packages:{'[+]':['texhtml']},allowTexHTML:true
},
};
</script>
<script defer src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js"></script>
</head>
<body>
\({<tex-html>Hi \(x=1\)</tex-html>}\)
</body>
</html>

Davide Cervone

unread,
Oct 20, 2025, 6:18:39 AMOct 20
to mathja...@googlegroups.com
MathJax does not recursively process math within <tex-html> tags.  (And ChatGPT isn't going to be able to help you with this.  I don't know where it got the <tex-math> idea from, but that's nonsense.)  The texhtml extension isn't really intended for managing large chunks of HTML, but rather to give you the ability to add form input elements into the math, and small things like that.  Your usage is pushing the limits.

It is possible. however, to tie into the tooltip-handling code and have it run MathJax on the result once the tooltip has opened.  Here is a configuration that does that.

MathJax = {
  loader: {
    load: ['[tex]/texhtml'],
    'output/chtml': {
      ready() {
        const {ChtmlMaction} = MathJax._.output.chtml.Wrappers.maction;
        const tooltip = ChtmlMaction.actions.get('tooltip');
        const actions = tooltip[0];
        tooltip[0] = (node, data) => {
          actions(node, data);
          for (const dom of node.dom) {
            const tip = dom.querySelector('mjx-tool');
            if (!tip.querySelector('mjx-html')) return;
            tip.style.visibility = 'hidden';
            const listener = (event) => {
              setTimeout(() => {
                MathJax.typesetPromise([tip])
                  .then(() => tip.style.visibility='');
              }, data.postDelay + 300);
              dom.removeEventListener('mouseover', listener);
            }
            dom.addEventListener('mouseover', listener);;
          }
        };
      },
    },
  },
  tex: {
    inlineMath: {'[+]': [['$', '$']]},
    packages: {'[+]': ['texhtml']},
    allowTexHTML: true,
  },
}

ChatGPT would not be able to come up with this for you, as no one has done this before so it has no patterns to draw on to solve this problem.  It has no understanding of the MathJax code base to be able to create a new idea like this.  You are wasting your time trying to get it to do this kind of thing.

I appreciate your trying to isolate the problem further, but I already knew that it was that math is not processed inside <tex-html> tags.  The code above will allow math inside the tooltips, but that doesn't extend to other uses of <tex-html> outside of tooltips.  That would be more difficult to handle, and I'm not planning to do that at the moment.

Davide


Reply all
Reply to author
Forward
0 new messages