Change positioning of Mathtips

79 views
Skip to first unread message

Andrew Murdza

unread,
Jun 18, 2022, 12:32:05 AM6/18/22
to MathJax Users
Thanks to Davide I have been able to use mathtips in my website. However, I want to do some CSS formatting for my math tips.

I want to make so it is possible to put a mathtip on the top (horizontally centered around the mathtip first argument (the text that will show the mathtip if you hover over it), not the whole equation), bottom (horizontally centered around the mathtip first argument), left (vertically centered around the mathtip first argument), and right (vertically centered around the mathtip first argument).

I also want there to be a little arrow-like extension pointing towards the mathtip first argument, background color, and colored text. I got the CSS to work for the above case but there are a few issues:
1. There is a little white rectangle with a black border that I want to get rid of
2. The above text starts at the right edge of the first argument of the mathtip instead of being horizontally centered and above the first argument.
3. I don't know how to do the CSS arrow-like extension and positioning for the other combinations (left, right, and below)
4. I want to make the tooltip appear more quickly.

I found this website https://docs.mathjax.org/en/v2.7-latest/options/output-processors/HTML-CSS.html which does what I want but it doesn't work when I try it. This is most likely because it was changed in version 3. I looked at the documentation for version 3 and I couldn't find the options in the 2.7 version. Is there a way to do it with a combination of CSS, Javascript, Html, and MathJax in version 3?

This is my website code

<!DOCTYPE html>
<html>

<head>
    <script src="https://www.w3schools.com/lib/w3.js"></script>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        MathJax = {
            loader: {},
            tex: {
                inlineMath: [['$', '$'], ['\\(', '\\)']],
                packages: { '[+]': ['bold-chars'] },
                macros: {
                    recip: ['\\frac{1}{#1}', 1],
                    h: ['\\frac{#1}{2}', 1],
                    eps: '\\varepsilon',
                    R: '\\mathbb{R}',
                    a: ['\left\vert #1 \right\vert}', 1],
                    p: ['\\left( #1 \\right)', 1],
                    iff: '\\Longleftrightarrow',
                    b: ['\\textcolor{bluee}{#1}', 1],
                    r: ['\\textcolor{redd}{#1}', 1],
                    pu: ['\\textcolor{purplee}{#1}', 1],
                    go: ['\\textcolor{goldd}{#1}', 1],
                    pi: ['\\textcolor{pinkk}{#1}', 1],
                    lb: ['\\textcolor{lightbluee}{#1}', 1],
                    g: ['\\textcolor{greenn}{#1}', 1],
                    frac: ['\\genfrac{} {} {2} {0} {#1}{#2}', 2],
                    beq: '\\mathrel{\\vcenter{\\rlap{\\Rule{2ex}{3px}{0px}}\\raise9px{\\Rule{2ex}{3px}{0px}}}}',
                    bm: '\\mathrel{\\vcenter{\\Rule{1.5ex}{2px}{0px}}}',
                    bp: '\\boldsymbol{+}'
                }
            },
            startup: {
                ready() {
                    const { MacroMap } = MathJax._.input.tex.SymbolMap;
                    const { Configuration } = MathJax._.input.tex.Configuration;
                    const BaseMethods = MathJax._.input.tex.base.BaseMethods.default;

                    new MacroMap('bold-chars', {
                        '=': ['Macro', String.raw`\mathrel{\vcenter{\rlap{\Rule{2ex}{3px}{0px}}\raise9px{\Rule{2ex}{3px}{0px}}}}`],
                        '-': ['Macro', String.raw`\mathrel{\vcenter{\Rule{20px}{2px}{0px}}}`],
                        '+': ['Macro', String.raw`\mathrel{\vcenter{\rlap{\kern7px\Rule{2px}{9px}{7px}}\Rule{16px}{2px}{0px}}}`]
                    }, BaseMethods);

                    Configuration.create('bold-chars', { handler: { character: ['bold-chars'] } });

                    MathJax.startup.defaultReady();
                }
            }
        };
    </script>
    <script type="text/javascript" src="path-to-MathJax/MathJax.js?config=TeX-AMS_HTML">
    </script>

    <script type="text/javascript" id="MathJax-script" async
        </script>
    <link rel="stylesheet" href="style.css">
    \(\definecolor{redd}{RGB}{232,9,0}\)
    \(\definecolor{bluee}{RGB}{0,77,255}\)
    \(\definecolor{purplee}{RGB}{152,102,255}\)
    \(\definecolor{goldd}{RGB}{204, 153, 0}\)
    \(\definecolor{pinkk}{RGB}{244, 136, 189}\)
    \(\definecolor{lightbluee}{RGB}{0, 176, 240}\)
    \(\definecolor{greenn}{RGB}{114, 221, 0}\)
</head>

<body>
    <script>document.documentElement.className += ' spoiler-js';</script>

    <div class="spoiler spoiler-state-expanded" text="Introduction">
        <div class="spoiler-content">
            <div class="row">
                <div class="column_left">
                    The slope of the line through the points $(\r{x_1},\g{y_1})$ and
                    $(\lb{x_2},\pu{y_2})$ is given below:
                    $$\begin{aligned}
                    \text{slope}&=\frac{\b{\text{vertical change}}}{\go{\text{horizontal change}}}\\[10pt]
                    &=\frac{\b{\mathtip{\text{change in }y}{\class{mathtipabove}{hi}}}}{\go{\text{change in
                    }x}}\\[10pt]
                    &=\frac{\b{\Delta y}}{\go{\Delta x}}\\[10pt]
                    &=\frac{\pu{y_2}- \g{y_1}}{\lb{x_2} + \r{x_1}}
                    \end{aligned}$$
                </div>
                <div class="column_right">
                    <iframe src="https://www.desmos.com/calculator/iu7nvx7gpp?embed" width="500" height="500"
                        style="border: 1px solid #ccc" frameborder=0></iframe>
                </div>
            </div>
        </div>
    </div>
    <div class="tooltip">Hover over me
        <span class="tooltiptext">Tooltip text</span>
    </div>
    <script src="spoiler.js"></script>
</body>

</html>

This is my relevant CSS code

/*Math tooltip*/
/* Tooltip text */
.mathtipabove {
  width: 120px;
  background-color: #555;
  color: #fff;
  text-align: center;
  padding: 5px 0;
  border-radius: 6px;

  /* Position the tooltip text */
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  margin-left: -60px;

  /* Fade in tooltip */
  visibility: visible;
  opacity: 1;
}

/* Tooltip arrow */
.mathtipabove::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

If it is helpful I can send the full CSS but it is very long and I didn't want to make the message too long to read.

Davide Cervone

unread,
Jun 23, 2022, 3:44:45 PM6/23/22
to mathja...@googlegroups.com
I want to make so it is possible to put a mathtip on the top (horizontally centered around the mathtip first argument (the text that will show the mathtip if you hover over it), not the whole equation), bottom (horizontally centered around the mathtip first argument), left (vertically centered around the mathtip first argument), and right (vertically centered around the mathtip first argument).

Here is some CSS that can be used for getting tooltips similar to what you are looking for on the top and the right (I leave the bottom and left as an exercise for you).

mjx-maction > mjx-tool > mjx-tip {
  box-shadow: none;
  background-color: #555;
  border: none;
  padding: 5px;
  border-radius: 6px;
  color: white;
}

mjx-maction.tip-top > mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(50% - 13px);
  top: calc(-100% - 15px);
  width: auto;
  height: auto;
  z-index: 1;
}
mjx-maction.tip-top > mjx-tool::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 10px;
  border-width: 9px 4px 0 4px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

mjx-maction.tip-right > mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(100% + 15px);
  top: calc(50% - 13px);
  width: auto;
  height: auto;
  z-index: 1;
}
mjx-maction.tip-right > mjx-tool::after {
  content: "";
  position: absolute;
  left: -9px;
  top: 8px;
  border-width: 4px 9px 4px 0;
  border-style: solid;
  border-color: transparent #555 transparent transparent;
}

To specify them, use \class{tip-top}{\mathtip{math}{tip} or \class{tip-right}{\mathtip{math}{tip}} (of course, you can use macros to make this easier).  

In your code, the lines:

<script type="text/javascript" src="path-to-MathJax/MathJax.js?config=TeX-AMS_HTML">
</script>

should be removed, as these look like you are loading v2, which you don't know and without replacing path-to-mathjax with an actual location for the MathJax.js file, it will not do anything anyway.

You also probably don't need

                    beq: '\\mathrel{\\vcenter{\\rlap{\\Rule{2ex}{3px}{0px}}\\raise9px{\\Rule{2ex}{3px}{0px}}}}',
                    bm: '\\mathrel{\\vcenter{\\Rule{1.5ex}{2px}{0px}}}',
                    bp: '\\boldsymbol{+}'

any longer, as the bold-chars package handled that better.

In order to make the tips appear more quickly, you can use

MathJax = {
  startup: {
    ready() {
      const {TooltipData} = MathJax._.output.common.Wrappers.maction;
      TooltipData.postDelay = 300;   // delay in milliseconds
      MathJax.startup.defaultReady();
    }
  }
};

to set the delay.  It is no longer a directly configurable parameter.  Note that you will have to merge this with the configuration that you already have.

Davide


Andrew Murdza

unread,
Jun 29, 2022, 6:22:29 PM6/29/22
to MathJax Users
Dear Davide,

I implemented the bottom and left. However, there is a problem when the tooltip is more than two letters. The tooltip text is always right-aligned. In the left tooltip case, this leads to the tooltip covering up part of the original text instead of being entirely on the left side of the text. Similarly, in the top and bottom tooltip cases, I want the text to be centered instead of going to the right side. I tried text-align: center, align-content: center, align-self: center, and text-align-last: center for the top tooltip case but none of them changed the positioning of the text. I found out that changing 50% - 13px to 50% - {a different number} px does what I want but the number replacing 13px depends on the length of the text in the tooltip. Is there a way to replace 13px with something that is a value that depends on the length of the text?

This is my html code with some parts omitted for brevity

<!DOCTYPE html>
<html>

<head>
    <script src="https://www.w3schools.com/lib/w3.js"></script>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        MathJax = {
            loader: { load: ['[tex]/color'] },
            tex: {
                inlineMath: [['$', '$'], ['\\(', '\\)']],
                packages: { '[+]': ['bold-chars', 'color'] },
                macros: {
                    recip: ['\\frac{1}{#1}', 1],
                    ... other short commands...
                    ttip: ['\\class{tip-top}{\\mathtip{#1}{#2}}', 2],
                    rtip: ['\\class{tip-right}{\\mathtip{#1}{#2}}', 2],
                    ltip: ['\\class{tip-left}{\\mathtip{#1}{#2}}', 2],
                    btip: ['\\class{tip-bot}{\\mathtip{#1}{#2}}', 2]
                }
            },
            startup: {
                ready() {
                    const { MacroMap } = MathJax._.input.tex.SymbolMap;
                    const { Configuration } = MathJax._.input.tex.Configuration;
                    const BaseMethods = MathJax._.input.tex.base.BaseMethods.default;

                    new MacroMap('bold-chars', {
                        '=': ['Macro', String.raw`\mathrel{\vcenter{\rlap{\Rule{2ex}{3px}{0px}}\raise9px{\Rule{2ex}{3px}{0px}}}}`],
                        '-': ['Macro', String.raw`\mathrel{\vcenter{\Rule{20px}{2px}{0px}}}`],
                        '+': ['Macro', String.raw`\mathrel{\vcenter{\rlap{\kern7px\Rule{2px}{9px}{7px}}\Rule{16px}{2px}{0px}}}`]
                    }, BaseMethods);

                    Configuration.create('bold-chars', { handler: { character: ['bold-chars'] } });

                    const { TooltipData } = MathJax._.output.common.Wrappers.maction;
                    TooltipData.postDelay = 10;   // delay in milliseconds

                    MathJax.startup.defaultReady();

                    MathJax.tex2mml(String.raw`
                    \definecolor{orange}{RGB}{253, 119, 0}
                    ...other colors
                `);
                }
            }
        };
    </script>

    <script type="text/javascript" id="MathJax-script" async
        </script>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <script>document.documentElement.className += ' spoiler-js';</script>
        <div class="spoiler-content">
                    The slope of the line through the points $(\r{x_1},\g{y_1})$ and
                    $(\lb{x_2},\pu{y_2})$ is given below:
                    $$\begin{aligned}
                    \text{slope}&=\frac{\b{\text{vertical change}}}{\go{\text{horizontal change}}}\\[10pt]
                    &=\frac{\b{\ttip{\text{change in }y}{hiiiiii}}}{\btip{\go{\text{change in }x}}{hiiiii}}\\[10pt]
                    &=\frac{\b{\Delta y}}{\go{\Delta x}}\\[10pt]
                    &=\frac{\pu{y_2}- \g{y_1}}{\lb{x_2} - \r{x_1}}
                    \end{aligned}$$
            </div>
</body>

</html>

This is the relevant part of my CSS code

mjx-maction>mjx-tool>mjx-tip {
  box-shadow: none;
  background-color: #555;
  border: none;
  padding: 5px;
  border-radius: 6px;
  color: white;
}

mjx-maction.tip-top>mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(50% - 13px);
  top: calc(-100% - 10px);
  width: auto;
  height: auto;
  z-index: 1;
  text-align: center;
  align-content: center;
  align-self: center;
  text-align-last: center;
}

mjx-maction.tip-top>mjx-tool::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 10px;
  border-width: 9px 4px 0 4px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

mjx-maction.tip-bot>mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(50% - 13px);
  top: calc(100% + 10px);
  width: auto;
  height: auto;
  z-index: 1;
}

mjx-maction.tip-bot>mjx-tool::after {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 10px;
  border-width: 9px 4px 0 4px;
  transform: rotate(180deg);
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}


mjx-maction.tip-right>mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(100% + 15px);
  top: calc(50% - 13px);
  width: auto;
  height: auto;
  z-index: 1;
}

mjx-maction.tip-right>mjx-tool::after {
  content: "";
  position: absolute;
  left: -9px;
  top: 8px;
  border-width: 4px 9px 4px 0;
  border-style: solid;
  border-color: transparent #555 transparent transparent;
}

mjx-maction.tip-left>mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(0% - 45px);
  top: calc(50% - 13px);
  width: auto;
  height: auto;
  z-index: 1;
}

mjx-maction.tip-left>mjx-tool::after {
  content: "";
  position: absolute;
  right: -9px;
  top: 8px;
  border-width: 4px 9px 4px 0px;
  transform: rotate(180deg);
  border-style: solid;
  border-color: transparent #555 transparent transparent;
}

Davide Cervone

unread,
Jun 30, 2022, 9:46:39 AM6/30/22
to mathja...@googlegroups.com
I implemented the bottom and left. However, there is a problem when the tooltip is more than two letters. The tooltip text is always right-aligned. In the left tooltip case, this leads to the tooltip covering up part of the original text instead of being entirely on the left side of the text.

You need to set the CSS for "right" rather than left for that case (and for the top on the bottom, you should use the "top" CSS to position it).

Similarly, in the top and bottom tooltip cases, I want the text to be centered instead of going to the right side.

That is somewhat more difficult.  (See below.)

I tried text-align: center, align-content: center, align-self: center, and text-align-last: center for the top tooltip case but none of them changed the positioning of the text.

That is because these are about the position of the text within the element, not the position of the element in relation to its container, which is what you need.  There is no direct CSS for that, so you have to work a bit harder.

I found out that changing 50% - 13px to 50% - {a different number} px does what I want but the number replacing 13px depends on the length of the text in the tooltip. Is there a way to replace 13px with something that is a value that depends on the length of the text?

Not using only CSS.

But here is a different approach.  This is the CSS for top and right, and again I leave left and bottom to you (you will need to use right and top positioning rather than left and bottom for that, as I mention above).

mjx-maction > mjx-tool > mjx-tip {
  box-shadow: none;
  border: none;
  padding: 0;
  display: flex;
  align-items: center;
}

mjx-maction > mjx-tool > mjx-tip > * {
  background-color: #555;
  padding: 5px;
  border-radius: 6px;
  color: white;
}

mjx-maction.tip-top > mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: 50%;
  top: calc(-100% - 15px);
  height: auto;
  z-index: 1;
}
mjx-maction.tip-top > mjx-tool > mjx-tip {
  flex-direction: column;
  width: 0;
}
mjx-maction.tip-top > mjx-tool> mjx-tip::after {
  content: "";
  position: absolute;
  top: 100%;
  border-width: 9px 4px 0 4px;
  border-style: solid;
  border-color: #555 transparent transparent transparent;
}

mjx-maction.tip-right > mjx-tool {
  bottom: auto ! important;
  right: auto ! important;
  left: calc(100% + 15px);
  top: 50%;
  width: auto;
  z-index: 1;
}
mjx-maction.tip-right > mjx-tool > mjx-tip {
  flex-direction: row;
  height: 0;
}
mjx-maction.tip-right > mjx-tool::after {
  content: "";
  position: absolute;
  left: -9px;
  top: -4px;
  border-width: 4px 9px 4px 0;
  border-style: solid;
  border-color: transparent #555 transparent transparent;
}

At this point, this is all just CSS and no longer MathJax specific (since you now know the selectors to use to apply styles to the MathJax output), so you are going to have to figure the rest out yourself.  I have done more on this than I should have already.

Davide

Reply all
Reply to author
Forward
0 new messages