javascripthtmlcssmathjax

Render MathJax within span dimension


I am programmatically creating HTML tags to display LaTeX formulas using MathJax. It seems that the formula is being rendered after the dimension of the <span> tag has been calculated. I want to ensure that the formula is rendered within the span boundaries. What is the fix I kindly ask!? enter image description here

script.js

formula = "${{{{{{x^2}^2}^2}^2}^2}^2}^2$"
question_div = document.createElement("div");
question_div.setAttribute("id", "q1");

let input = document.createElement("input");
input.name = "a1";
input.id = "a1";
input.type = "radio";
let label = document.createElement("label");
let span_label = document.createElement("span");
span_label.setAttribute("class", "my-span");

span_label.innerText = formula;

label.appendChild(input);
label.appendChild(span_label);

question_div.appendChild(label);
document.body.appendChild(question_div);

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>title</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
<script>
MathJax = {
  tex: {
    inlineMath: [['$', '$'], ['\\(', '\\)']]
  }
};
</script>
<script id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
</script>
    <script type="text/javascript" src="script.js"></script>
  </body>
</html>

styles.css

label {
  border: 1px solid rgb(199, 199, 199);
  margin: 5px;
  padding: 4px;
  cursor: pointer;
}

div{
  padding-top:8px;
  padding-bottom:8px;
}

.my-span{
  padding-left:8px;
}

Solution

  • An element with display: inline, like a <span>, will have its height and depth (for purposes of borders and backgrounds) be the height and depth of the font in use in the element, regardless of the height and depth of other elements within it. For example:

    #span1 {
      border: 1px solid black;
    }
    
    #span2 {
      display: inline-block;
      height: 4em;
      width: 1em;
      vertical-align: -1.75em;
      background-color: red;
    }
    <span id="span1">This span has a tall element
    <span id="span2"></span> but its height stays the same</span>

    So what you are seeing with the MathJax output is the correct result.

    In order to have its height and depth match the content, you need to use display: inline-block (there are other values that also work for this).

    #span1 {
      display: inline-block;
      border: 1px solid black;
    }
    
    #span2 {
      display: inline-block;
      height: 4em;
      width: 1em;
      vertical-align: -1.75em;
      background-color: red;
    }
    <span id="span1">This span has a tall element
    <span id="span2"></span> and its height matches that</span>

    So for your example, adding display: inline-block to your label CSS, you get

    formula = "${{{{{{x^2}^2}^2}^2}^2}^2}^2$"
    question_div = document.createElement("div");
    question_div.setAttribute("id", "q1");
    
    let input = document.createElement("input");
    input.name = "a1";
    input.id = "a1";
    input.type = "radio";
    let label = document.createElement("label");
    let span_label = document.createElement("span");
    span_label.setAttribute("class", "my-span");
    
    span_label.innerText = formula;
    
    label.appendChild(input);
    label.appendChild(span_label);
    
    question_div.appendChild(label);
    document.body.appendChild(question_div);
    label {
      display: inline-block;
      border: 1px solid rgb(199, 199, 199);
      margin: 5px;
      padding: 4px;
      cursor: pointer;
    }
    
    div{
      padding-top:8px;
      padding-bottom:8px;
    }
    
    .my-span{
      padding-left:8px;
    }
    <script>
    MathJax = {
      tex: {
        inlineMath: [['$', '$'], ['\\(', '\\)']]
      }
    };
    </script>
    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
    </script>