应优先使用MathML或KaTeX排版数学公式,而非HTML的<sub>/<sup>标签;前者语义准确、渲染稳定,后者兼容性好、自动处理嵌套与间距。

sub 和 sup 在数学公式里根本撑不起结构
直接用 <sub> 和 <sup> 写公式,很快就会发现对齐错乱、嵌套失效、字号比例失控——它们不是为公式设计的,只是行内文本下标/上标语义标签。
常见错误现象:CO<sub>2</sub> 看起来还行,但遇到 H<sub>2</sub>O<sup>−</sup><sup>2</sup> 就会把负号和数字叠歪;多层嵌套如 x<sup>n<sub>i</sub></sup> 在多数浏览器里渲染异常;CSS 控制字号时,font-size 对 <sub> 的缩放比例不统一(Chrome 是 0.8em,Firefox 是 0.75em)。
- 适用场景仅限简单化学式、单位符号(如
m<sup>2</sup>)、脚注编号(如text<sup>1</sup>) - 不要尝试用
<sub>/<sup>搭配<span>手动调位置——CSS 的vertical-align和line-height会因父容器字体、行高不同而漂移 - 真正需要排版公式时,优先走 MathML 或 KaTeX 渲染路径,而不是硬塞
<sub>
MathML 是 HTML 原生支持的公式方案,但得写对结构
MathML 的 <msub>、<msup>、<msubsup> 才是专为数学上下标设计的元素,浏览器原生解析,无需 JS 加载,语义准确且排版稳定。
关键点:不能把 <msub> 当成 <sub> 的增强版来用——它必须包裹两个子元素:<msub><mi>x</mi><mn>1</mn></msub>,第一个是基底,第二个是下标。漏掉任意一个,或顺序颠倒,都会渲染失败或退化为空白。
立即学习“前端免费学习笔记(深入)”;
-
<msubsup>用于同时有上下标,结构是<msubsup><mi>a</mi><mn>i</mn><mn>j</mn></msubsup>(基底、下标、上标) - 避免混用 HTML 标签和 MathML:比如在
<msub>里塞<div>或<p>,只允许<mi>(标识符)、<mn>(数字)、<mo>(运算符)等 MathML 内建元素 - Safari 对 MathML 支持最完整,Chrome 自 114 起启用实验性支持(需开启
chrome://flags/#enable-mathml),Firefox 始终可用
KaTeX 是当前最稳妥的前端公式方案
如果项目里已有构建流程或能引入轻量 JS,KaTeX 比 MathML 更易落地——它把 LaTeX 语法转成纯 HTML+CSS,兼容性好、渲染快、样式可控,而且自动处理上下标嵌套、括号伸缩、字体间距等细节。
示例:\(x_{i}^{j} + \sum_{k=1}^{n} a_k\) 经 KaTeX 处理后,x_{i}^{j} 会生成带精确定位的 <span class="mrow">...</span> 结构,而不是靠 vertical-align 抖动。
- 加载方式:CDN 引入
katex.min.css和katex.min.js,再调用katex.render()或用\( ... \)包裹 LaTeX 片段 - 注意转义:HTML 中写
\(E = mc^2\),而不是$E = mc^2$(KaTeX 默认禁用美元符号,防冲突) - 性能影响:单页公式少于 50 个时几乎无感;超过时建议用
renderToString预渲染静态内容,避免客户端重复解析
纯 CSS 方案只适合极简需求,且要设底线
真不想加 JS、又用不了 MathML?可以用 vertical-align + 固定 font-size 模拟,但必须接受局限性:无法自动适配字体、不支持斜体/粗体继承、上下标无法独立设置字体族。
典型写法:<span class="sup">2</span> 配 CSS:.sup { font-size: .7em; vertical-align: super; }。问题在于“super”值是相对当前行高的,若父元素 line-height 是 1.2,那实际偏移量就不可控。
- 必须限定使用范围:仅限单字符、无嵌套、字体固定(如只在
<code>或等宽环境中用) - 绝对不要用
position: relative+top模拟——会导致行高塌陷、换行错位、屏幕阅读器无法识别语义 - 移动端尤其危险:iOS Safari 对
vertical-align: super的计算在缩放时抖动明显,测试至少覆盖 320px–414px 宽度
复杂公式永远不该靠 CSS 补丁堆出来。哪怕只多一层括号或一个分式,就该切到 KaTeX 或 MathML——这不是过度设计,是避免三天后改一行代码崩掉整页排版。



















