网页里碰上数学公式的指数、化学方程式的角标,或者文献引用的小数字,浏览器默认渲染的上标(<sup>)和下标(<sub>)经常闹脾气。手机屏幕上缩成蚂蚁腿,大显示器上又肿成大头娃娃。这个问题根源在于浏览器一直用font-size: smaller来粗暴处理,换算下来大概0.83倍的缩放比例。当年简单文档还行,现在响应式设计里字体大小本身就忽大忽小,静态缩放直接翻车。下面整一套纯CSS的流体计算方案,让上标下标跟着环境自动拿捏分寸。
静态缩放翻车
看看传统做法有多坑。浏览器给<sup>和<sub>默认加上font-size: smaller,相当于把字号压到父元素的83%左右。假如正文用clamp()做了流体字体,比如最小16px最大24px,那么上标就变成13px到20px之间跳动。问题在于这个缩放是线性的,小尺寸下13px勉强能看,但大尺寸下20px配上默认的上移偏移量,整个字符会戳出正文行高一大截。更别说某些浏览器还会把上标的vertical-align搞成super,直接脱离行盒模型,导致行间距乱飘。这就像拿同一把勺子去舀咖啡和舀汤,勺子大小没变,但咖啡杯和汤碗口径差太多,咋舀都别扭。
流体计算原理
解决思路是让上标字号的缩放曲线不是简单比例,而是混合固定像素和相对单位。核心代码长这样:
sup, sub {
font-size: calc(0.5em + 4px);
vertical-align: baseline;
position: relative;
top: calc(-0.5 * 0.83 * 2 * (1em - 4px));
}
sub {
top: calc(0.25 * 0.83 * 2 * (1em - 4px));
}这里calc(0.5em + 4px)是个混合油门。当父元素字号很小(比如14px)时,0.5em贡献7px,加上4px得11px,固定部分占大头,保证小屏幕下不会缩成渣。当父元素字号很大(比如32px)时,0.5em贡献16px,加上4px得20px,比例部分开始主导,避免长得太夸张。这招好比混动车,低速用电(固定px)保证起步不肉,高速用油(相对em)防止油耗爆炸。
手把手调参数
把上面那段CSS扔进项目全局样式表里,上标下标立马变听话。但直接抄作业可能遇到两个情况:第一,某些老旧浏览器不认识calc(),需要套一层@supports做安全网;第二,不同字体对上标位置的手感不一样,得微调偏移量。
安全网写法
@supports (font-size: calc(1em + 1px)) {
sup, sub {
font-size: calc(0.5em + 4px);
vertical-align: baseline;
position: relative;
top: calc(-0.5 * 0.83 * 2 * (1em - 4px));
}
sub {
top: calc(0.25 * 0.83 * 2 * (1em - 4px));
}
}不认识的浏览器会直接忽略整块,回退到默认样式,虽然丑点但不会崩。
微调偏移量
代码里0.83这个因子是为了匹配浏览器默认的smaller缩放比例。如果觉得上标飘太高或压太低,可以改这个系数。比如某款艺术字体基线偏下,试试把0.83换成0.75,再配合调整后面的乘数。更暴力的方式是直接在浏览器开发者工具里改top值,实时预览到舒服为止。
实战代码流程
拿一个实际文章页面试刀。假设正文容器字号用流体方案:font-size: clamp(16px, 4vw, 28px);。那么上标默认会缩到0.83倍约13~23px,加上流体计算后变成0.5em+4px,算出来是12~18px。明显大尺寸下更克制,不会出现23px的巨无霸上标。
完整插入步骤
- 打开项目的全局CSS文件(比如
main.css或typography.css)。 - 把上面带
@supports的代码块粘贴到文件底部,避免被其他样式覆盖。 - 硬重启浏览器缓存(Ctrl+F5或Cmd+Shift+R),检查页面上的数学公式和化学式。
- 调出开发者工具,选中一个
<sup>元素,在计算样式中看font-size实际值是否随窗口缩放动态变化。
如果发现上标和下标的垂直位置跟正文文字打架,比如上标盖住了上方字母,那就调整top里的0.5这个系数。公式里的0.5代表默认上移半个字符高度,改成0.45会让上标压低一丢丢。
备胎方案对比
不想搞复杂数学的话,还有两种土办法。不过各有各的坑,放表格里对比看清楚:
| 方案 | 优点 | 坑点 |
|---|---|---|
| 固定em缩放 | 代码少 兼容性好 | 大屏下容易比例失调 |
| 媒体查询断点 | 能精确控制每个尺寸段 | 断点之间会突变 维护量爆炸 |
| 流体calc | 平滑过渡 一行CSS搞定 | 需要调偏移系数 老浏览器要垫片 |
固定em缩放写法:sup, sub { font-size: 0.75em; }。简单但粗暴,32px正文下上标变24px,还是太大。媒体查询断点:@media (min-width: 1200px) { sup, sub { font-size: 18px; } }。这种在每个断点内是静止的,窗口拉动时会突然跳变,强迫症受不了。
流体方案里那个calc(0.5em + 4px)不是死公式。假如项目里的正文最小16px最大40px,可以改成calc(0.4em + 6px),让小尺寸下更清晰。改了字号之后,偏移量里的1em - 4px也要跟着动,因为4px变成了6px。完整调整范例:
大缩放版本(适合粗犷风格设计)
sup, sub {
font-size: calc(0.6em + 3px);
top: calc(-0.5 * 0.83 * 2 * (1em - 3px));
}小缩放版本(适合精致小字排版)
sup, sub {
font-size: calc(0.4em + 5px);
top: calc(-0.5 * 0.83 * 2 * (1em - 5px));
}改完记得同步调整sub的top值,把0.5换成0.25就行。这些数字看着头大,但本质就两件事:控制字号不要疯长,控制偏移不要撞车。拿实际页面里的长段落多试几次,找到自家设计系统的甜点位。
