上标和下标在手机电脑上大小不一,流体CSS缩放到底怎么调?

2,412字
10–15 分钟
in

网页里碰上数学公式的指数、化学方程式的角标,或者文献引用的小数字,浏览器默认渲染的上标(<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的巨无霸上标。

完整插入步骤

  1. 打开项目的全局CSS文件(比如main.csstypography.css)。
  2. 把上面带@supports的代码块粘贴到文件底部,避免被其他样式覆盖。
  3. 硬重启浏览器缓存(Ctrl+F5或Cmd+Shift+R),检查页面上的数学公式和化学式。
  4. 调出开发者工具,选中一个<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));
}

改完记得同步调整subtop值,把0.5换成0.25就行。这些数字看着头大,但本质就两件事:控制字号不要疯长,控制偏移不要撞车。拿实际页面里的长段落多试几次,找到自家设计系统的甜点位。