如何在 HTML 中写数学公式?

10,878 阅读9分钟

一些简单的数学公式,我们直接使用 HTML 标签就可以写出来,比如下面这个公式1

(x2+y21)3x2y3=0\left( x^{2}+y^{2}-1\right) ^{3}-x^{2}y^{3}=0

就可以利用 HTML 的<sup>标签实现:

(x<sup>2</sup> + y<sup>2</sup> - 1)<sup>3</sup> - x<sup>2</sup>y<sup>3</sup> = 0

但是再复杂点的公式,HTML 就无能为力了,比如这个公式2

f(t)=limnn!ntt(t+1)(t+n)=1tn=1(1+1n)t1+tn=erttn=1(1+tn)1etnf\left( t\right) =\lim _{n\rightarrow \infty }\dfrac{n!n^{t}}{t\left( t+1\right) \ldots \left( t+n\right) }=\dfrac{1}{t}\prod ^{\infty }_{n=1}\dfrac{\left( 1+\dfrac{1}{n}\right) ^{t}}{1+\dfrac{t}{n}}=\dfrac{e^{-rt}}{t}\prod ^{\infty }_{n=1}\left( 1+\dfrac{t}{n}\right) ^{-1}e^{\dfrac{t}{n}}

像这种复杂的数学公式,我们可以使用 MathML 来描述。

数学标记语言(Mathematical Markup Language, MathML),是一种基于 XML 的标准,用来描述数学符号和公式。它的目标是把数学公式集成到万维网和其他文档中。从2015年开始,MathML 成为了 HTML5 的一部分和 ISO 标准。---- 维基百科

公式2用 MathML 描述就是这样的:

<math>
  <mi> f </mi>
  <mrow>
    <mo> ( </mo>
    <mi> t </mi>
    <mo> ) </mo>
  </mrow>
  <mo> = </mo>
  <munder>
    <mrow>
      <mi> lim </mi>
    </mrow>
    <mrow>
      <mi> n </mi>
      <mo> &#x2192;
        <!-- rightwards arrow -->
      </mo>
      <mi> &#x221E;
        <!-- infinity -->
      </mi>
    </mrow>
  </munder>
  <mfrac>
    <mrow>
      <mi> n </mi>
      <mo> ! </mo>
      <msup>
        <mrow>
          <mi> n
            <!-- greek capital letter lambda -->
          </mi>
        </mrow>
        <mrow>
          <mi> t </mi>
        </mrow>
      </msup>
    </mrow>
    <mrow>
      <mi> t </mi>
      <mrow>
        <mo> ( </mo>
        <mi> t </mi>
        <mo> + </mo>
        <mn> 1 </mn>
        <mo> ) </mo>
      </mrow>
      <mo> &#x2026;
        <!-- horizontal ellipsis -->
      </mo>
      <mrow>
        <mo> ( </mo>
        <mi> t </mi>
        <mo> + </mo>
        <mi> n </mi>
        <mo> ) </mo>
      </mrow>
    </mrow>
  </mfrac>
  <mo> = </mo>
  <mfrac>
    <mrow>
      <mn> 1 </mn>
    </mrow>
    <mrow>
      <mi> t </mi>
    </mrow>
  </mfrac>
  <munderover>
    <mrow>
      <mo> &#x220F;
        <!-- n-ary product -->
      </mo>
    </mrow>
    <mrow>
      <mi> n </mi>
      <mo> = </mo>
      <mn> 1 </mn>
    </mrow>
    <mrow>
      <mi> &#x221E;
        <!-- infinity -->
      </mi>
    </mrow>
  </munderover>
  <mfrac>
    <mrow>
      <msup>
        <mrow>
          <mrow>
            <mo> ( </mo>
            <mn> 1 </mn>
            <mo> + </mo>
            <mfrac>
              <mrow>
                <mn> 1 </mn>
              </mrow>
              <mrow>
                <mi> n </mi>
              </mrow>
            </mfrac>
            <mo> ) </mo>
          </mrow>
        </mrow>
        <mrow>
          <mi> t </mi>
        </mrow>
      </msup>
    </mrow>
    <mrow>
      <mn> 1 </mn>
      <mo> + </mo>
      <mfrac>
        <mrow>
          <mi> t </mi>
        </mrow>
        <mrow>
          <mi> n </mi>
        </mrow>
      </mfrac>
    </mrow>
  </mfrac>
  <mo> = </mo>
  <mfrac>
    <mrow>
      <msup>
        <mrow>
          <mi> e </mi>
        </mrow>
        <mrow>
          <mo> - </mo>
          <mi> r </mi>
          <mi> t </mi>
        </mrow>
      </msup>
    </mrow>
    <mrow>
      <mi> t </mi>
    </mrow>
  </mfrac>
  <munderover>
    <mrow>
      <mo> &#x220F;
        <!-- n-ary product -->
      </mo>
    </mrow>
    <mrow>
      <mi> n </mi>
      <mo> = </mo>
      <mn> 1 </mn>
    </mrow>
    <mrow>
      <mi> &#x221E;
        <!-- infinity -->
      </mi>
    </mrow>
  </munderover>
  <msup>
    <mrow>
      <mrow>
        <mo> ( </mo>
        <mn> 1 </mn>
        <mo> + </mo>
        <mfrac>
          <mrow>
            <mi> t </mi>
          </mrow>
          <mrow>
            <mi> n </mi>
          </mrow>
        </mfrac>
        <mo> ) </mo>
      </mrow>
    </mrow>
    <mrow>
      <mo> - </mo>
      <mn> 1 </mn>
    </mrow>
  </msup>
  <msup>
    <mrow>
      <mi> e </mi>
    </mrow>
    <mrow>
      <mfrac>
        <mrow>
          <mi> t </mi>
        </mrow>
        <mrow>
          <mi> n </mi>
        </mrow>
      </mfrac>
    </mrow>
  </msup>
</math>

将上面的代码复制到本地的 HTML 文件中,使用 FireFox 或者 Safari 浏览器打开即可看到效果。你还可以针对每个标签设置不同的 CSS 样式。

MathML 代码生成

从上面这个示例就知道,MathML 非常复杂,光这一个公式就够写一天了。不过我们可以使用工具(点击访问)自动生成 MathML 代码。

MathML 元素

顶层元素 <math>

MathML 的顶级元素。类似于 HTML 中的<body>

<math>
  ...
</math>

字符/符号元素

  • <mi>元素指示内容应该作为标识符呈现,比如函数名、变量或符号常量。还可以在其中使用任意文本来标记术语。

    <math>
      <mi> x </mi> <!-- x -->
      <mi> &pi; </mi>  <!-- π -->
    </math>
    
  • <mn>元素表示一个数值文字,它通常是一串数字,并带有可能的分隔符(点或逗号)。但是,它也允许在其中包含任意文本,实际上是一个数字量,例如 "11"。

    <math>
      <mn> 1 </mn>
      <mn> 2e10 </mn>
    </math>
    
  • <mo>元素表示运算,包括括号等“运算符”、逗号和分号等分隔符。

      <math>
        <mn> 5 </mn>
        <mo> + </mo>
        <mn> 5 </mn>
      </math>
    
  • <ms>元素表示要由编程语言和计算机代数系统解释的字符串文字。 默认情况下,字符串文字显示为用双引号(")括起来;通过使用 lquote 和 rquote 属性,可以设置要显示的自定义字符。请注意,除非引号是字符串文字的一部分,否则不应该指定引号。<ms>元素的内容本身不是 ASCII 字符串,而是一系列字符以及<mglyph><malignmark>元素。

    <math>
      <ms lquote="„" rquote="“"> abc </ms> <!-- „abc“ -->
    </math>
    
  • <mspace>元素用来表示一段空白,空白的大小由它自身的属性(width,height,depth)决定。

    <math>
      <!-- depth: 基线下方的空白高度 -->
      <!-- height: 基线上方的空白高度 -->
      <mspace depth="40px" height="20px" />
      <!-- width: 空白的宽度 -->
      <mspace width="100px" />
    </math>
    
  • <mtext>元素用于呈现没有符号意义的任意文本,比如注释或注释。要显示有符号意义的文本,可以使用<mi><mo>

    <math> 
      <mtext> Theorem of Pythagoras </mtext>  
      <mtext> /* comment here */ </mtext>
    </math>
    

通用布局元素

  • <menclosed>元素将其内容呈现在由 notation 属性指定的封闭符号中。支持 17 中不同的封闭符号,详细信息查看文档
    <!-- 求阶乘 -->
    <math> 
      <menclose notation="madruwb">
        <msup><mi>a</mi><mn>2</mn></msup>
        <mo>+</mo>
        <msup><mi>b</mi><mn>2</mn></msup>
      </menclose>
    </math>
    
  • <merror>元素用于将内容显示为错误消息。在 Firefox 中,此错误消息的呈现方式与典型的 XML 错误消息类似。注意,当 MathML 标记是错误的或不是格式良好的 XML 时,不会抛出此错误。仍然会得到一个 XML 解析错误(在 MathML 的 XHTML 表示法的情况下),它与<merror>无关。
    <math>
      <merror>
        <mrow>
          <mtext>除以0:</mtext>
          <mfrac>
            <mn> 1 </mn>
            <mn> 0 </mn>
          </mfrac>
        </mrow>
      </merror>
    </math>
    
  • <mfrac>元素用于显示分数。
    <math>
      <mfrac> <!-- a / b -->
        <mi> a </mi>
        <mi> b </mi>
      </mfrac>
    </math>
    
  • <mphantom>元素以不可见的方式呈现,但是尺寸(例如高度、宽度和基线位置)仍然保持不变。类似于 CSS 中的visibility: hidden
    <math>
      <mrow>
        <mi> x </mi>
        <mo> + </mo> 
        <mphantom> <!-- mphantom 标签内的元素不可见 -->
          <mi> y </mi>
          <mo> + </mo>
        </mphantom>
        <mi> z </mi>
      </mrow>
    </math>
    
  • <mroot>元素用来表示一个有明确根指数的根式。它接受两个参数,语法如下:<mroot> base index </mroot>
    <math>
      <mroot>
        <mi>x</mi>
        <mn>3</mn>
       </mroot>
    </math>
    
  • <mrow>元素用于对连续多行表达式的不同子表达式进行分组,一条子表达式通常算作一行,至少包含一或多个操作符与其运算对象(比如 <mi><mn>)。
  • <msqrt>元素用于表示一个平方根(不显示根指数)。它只接受一个参数,语法如下:<msqrt> base </msqrt>
    <math>
      <msqrt>
        <mi>x</mi>
      </msqrt>
    </math>
    
  • <mstyle>元素更改其子元素的样式。
<math> 
  <mstyle displaystyle="true" mathcolor="teal">
    <mrow>
      <munderover>
        <mo stretchy="true" form="prefix">&sum;</mo>
        <mrow>
          <mi>i</mi>
          <mo form="infix">=</mo>
          <mn>1</mn>
        </mrow>
        <mi>n</mi>
      </munderover>
      <mstyle displaystyle="true">
        <mfrac>
          <mn>1</mn>          
          <mi>n</mi>
        </mfrac>
      </mstyle>
   </mrow>
  </mstyle>
</math>

边标和角标元素

  • <msub>元素用来为表达式加下标,语法如下:<msub> base subscript </msub>
    <math>
      <msub>
        <mi>X</mi>
        <mn>1</mn>
      </msub>
    </math>
    
  • <msubsup> 元素用于为表达式同时附加上角标和下角标。它的语法如下:<msubsup> base subscript superscript </msubsup>
    <math displaystyle="true">   
      <msubsup>
        <mo> &#x222B;<!-- 积分符号 --> </mo>
        <mn> 0 </mn>
        <mn> 1 </mn>
      </msubsup>
    </math>
    
  • <msup> 元素用于为表达式加上标。
    <math>
      <msup>
        <mi>X</mi>
        <mn>2</mn>
    </msup> 
    
``` - ``元素表示同时出现在上面和下面。 ```html ∫ 0 ∞ ```

表格数学

<mtable>,<mtr>,<mtd>元素类似于 HTML 中的<table>,<tr>,<td>

<math>
  <mtable>
    <mtr>
      <mtd><mi>A</mi></mtd>
      <mtd><mi>B</mi></mtd>
      <mtd><mi>C</mi></mtd>
    </mtr>
  </mtable>
</math>

数学符号

代数符号

符号HTML 字符实体Hex 码
+&plus;&#x2B;加号
&minus;&#x2212;减号
×&times;&#x00d7;乘号
÷&divide;&#x00f7;除号
&ne;&#x2260;不等号
&asymp;&#x2248;约等于
<&lt;&#x003c;小于
&le;&#x2264;小于等于
>&gt;&#x003e;大于
&ge;&#x2265;大于等于
±&plusmn;&#x00b1;正负号
&prop;&#x221d;正比于
&sum;&#x2211;求和符
&prod;&#x220f;求积运算或直积运算
&lfloor;&#x230a;向下取整左括号
&rfloor;&#x230b;向下取整右括号
&lceil;&#x2308;向上取整左括号
&rceil;&#x2309;向上取整右括号

微积分符号

符号HTML 字符实体Hex 码
&prime;&#x2032;单引号(一阶导数)
&Prime;&#x2033;双引号(二阶导数)
&tprime;&#x2034;三引号(三阶导数)
&part;&#x2202;偏导数
δ&delta;&#x0394;变分
&nabla;&#x2207;梯度算子
&int;&#x222b;积分
&Int;&#x222c;二重积分
&tint;&#x222d;三重积分
&qint;&#x2a0c;四重积分
&conint;&#x222e;曲线积分
&cwconint;&#x2232;顺时针曲线积分
&awconint;&#x2233;逆时针曲线积分
&Conint;&#x222f;曲面积分
&Cconint;&#x2230;体积积分
&infin;&#x221e;无穷大

省略符号

符号HTML 字符实体Hex 码
&hellip;&#x2026;水平省略号
&vellip;&#x22ee;垂直省略号
&ctdot;&#x22ef;中线水平省略号
&utdot;&#x22f0;对角省略号
&dtdot;&#x22f1;对角省略号

函数符号

符号HTML 字符实体Hex 码
&sdot;&#x22c5;点积
&Cross;&#x2a2f;叉积
&Vert;&#x2016;
&lang;&#x27e8;左尖括号
&rang;&#x27e9;右尖括号
&compfn;&#x2218;复合函数
&rarr;&#x2192;函数映射
&mapsto;&#x21a6;具体的函数映射
ı&imath;&#x0131;没有点的字母 i
ȷ&jmath;&#x0237;没有点的字母 j

几何符号

符号HTML 字符实体Hex 码
°&deg;&#x00b0;度数
&ang;&#x2220;角度
&angmsd;&#x2221;测量角度
&angrt;&#x221f;直角
&vangrt;&#x299c;直角
&lrtri;&#x22bf;直角三角形
&cir;&#x25cb;
&xutri;&#x25b3;三角形
&squ;&#x25a1;方形
&fltns;&#x25b1;平行四边形
&spar;&#x2225;平行
&npar;&#x2226;不平行
&perp;&#x22a5;垂直
&cong;&#x2245;全等
&rarr;&#x2192;射线
&harr;&#x2194;直线
-(n/a)&#x002d;线段

希腊字母

符号HTML 字符实体Hex 码
α/Α&alpha;/&Alpha;&#x03b1;/&#x0391;
β/Β&beta;/&Beta;&#x03b2;/&#x0392;
γ/Γ&gamma;/&Gamma;&#x03b3;/&#x0393;
δ/Δ&delta;/&Delta;&#x03b4;/&#x0394;
ε/Ε&epsilon;/&Epsilon;&#x03b5;/&#x0395;
ζ/Ζ&zeta;/&Zeta;&#x03b6;/&#x0396;
η/Η&eta;/&Eta;&#x03b7;/&#x0397;
θ/Θ&theta;/&Theta;&#x03b8;/&#x0398;
ι/Ι&iota;/&Iota;&#x03b9;/&#x0399;
κ/Κ&kappa;/&Kappa;&#x03ba;/&#x039a;
λ/Λ&lambda;/&Lambda;&#x03bb;/&#x039b;
μ/Μ&mu;/&Mu;&#x03bc;/&#x039c;
ν/Ν&nu;/&Nu;&#x03bd;/&#x039d;
ξ/Ξ&xi;/&Xi;&#x03be;/&#x039e;
ο/Ο&omicron;/&Omicron;&#x03bf;/&#x039f;
π/Π&pi;/&Pi;&#x03c0;/&#x03a0;
ρ/Ρ&rho;/&Rho;&#x03c1;/&#x03a1;
σ/Σ&sigma;/&Sigma;&#x03c3;/&#x03a3;
τ/Τ&tau;/&Tau;&#x03c4;/&#x03a4;
υ/Υ&upsilon;/&Upsilon;&#x03c5;/&#x03a5;
φ/Φ&phi;/&Phi;&#x03c6;/&#x03a6;
χ/Χ&chi;/&Chi;&#x03c7;/&#x03a7;
ψ/Ψ&psi;/&Psi;&#x03c8;/&#x03a8;
ω/Ω&omega;/&Omega;&#x03c9;/&#x03a9;

不可见运算符

符号HTML 字符实体Hex 码
&af;&#x2061;用于指定函数应用程序
&it;&#x2062;用于指定不可见的乘法
&ic;&#x2063;用于指定不可见分隔符
(n/a)&#x2064;用于指定不可见的加法

逻辑符号

符号HTML 字符实体Hex 码
¬&not;&#x00ac;
&and;&#x2227;
&or;&#x2228;
&veebar;&#x22bb;异或
&forall;&#x2200;全称量词
&exist;&#x2203;存在量词
&rArr;&#x21d2;实质蕴涵
&hArr;&#x21d4;实质等价
&EmptySmallSquare;&#x25fb;必要
&loz;&#x25ca;可能
&vdash;&#x22a2;推论
&Vdash;&#x22a8;包含
&because;&#x2235;因为
&there4;&#x2234;所以

集合符号

符号HTML 字符实体Hex 码
&empty;&#x2205;空集
&isin;&#x2208;属于
&notin;&#x2209;不属于
&sube;&#x2286;包含于
&nsube;&#x2288;不包含于
&sub;&#x2282;真子集
&nsub;&#x2284;非真子集
&supe;&#x2287;超集
&nsupe;&#x2289;非超集
&sup;&#x2283;真超集
&nsup;&#x2285;非真超集
&cap;&#x2229;交集
&cup;&#x222a;并集
&ssetmn;&#x2216;补集

浏览器兼容性

兼容性解决方案

  1. MathJax.js

MathJax.js 是一个数学公式渲染工具,它会将 MathML 标签转换为 HTML 标签,并为其添加特定的 CSS 样式。

在网页头部加入一行代码即可:

<html>
  <head>
    ...
    <script src="http://fred-wang.github.io/mathjax.js/mpadded-min.js"></script>
    ...
  </head>
  ...
</html>

mpadded-min.js 这个 JS 文件所做的就是在页面加载后先判断文档中是否使用了 MathML,如果有使用且当前浏览器不兼容,就将 MathJax.js 加载到页面中,并下载特定的字体文件。其渲染效果和 FireFox 这种原生支持 MathML 的浏览器相差无几,缺点是需要加载的文件较多(9 个文件,大约 400KB),速度较慢。

  1. mathml.css

mathml.css 提供一个简易版的适配方案,同样是先判断如果使用了 MathML 且当前浏览器不兼容,那么将会加载一个简易的 CSS 样式表,对数学公式的布局做一个简单的模拟,其渲染效果并不好,但是胜在轻量。

<html>
  <head>
    ...
    <script src="http://fred-wang.github.io/mathml.css/mspace.js"></script>
    ...
  </head>
  ...
</html>

公式2的不同效果: