Featured image of post Android移动端 line-height 垂直居中出现偏移

Android移动端 line-height 垂直居中出现偏移

问题

在开发的时候遇到的一个问题: 移动端安卓手机上使用 line-height 属性, 让它的值等于 height, 结果发现是不居中的, 统一的都有向上偏移的趋势.

Android移动端lineheight垂直居中出现偏移-2023-11-30-14-04-12

Android移动端lineheight垂直居中出现偏移-2023-11-30-14-04-18

css 这样写的.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.btn {
  width: 1.46rem;
  font-size: 0.28rem;
  height: 0.56rem;
  line-height: 0.56rem;
  border-radius: 0.56rem;
  background: #fedc53;
  color: #6e3d00;
  text-align: center;
}

原因

是 Android 在排版计算的时候参考了 primyfont 字体的相关属性(即 HHead Ascent、HHead Descent 等),而 primyfont 的查找是看font-family里哪个字体在 fonts.xml 里第一个匹配上,而原生 Android 下中文字体是没有 family name 的,导致匹配上的始终不是中文字体,所以解决这个问题就要在font-family里显式申明中文,或者通过什么方法保证所有字符都 fallback 到中文字体。

解决

  1. 针对 Android 7.0+设备:
    <html>上设置 lang 属性:<html lang="zh-cmn-Hans">,同时 font-family 不指定英文,如 font-family: sans-serif 。这个方法是利用了浏览器的字体 fallback 机制,让英文也使用中文字体来展示,blink 早期的内核在 fallback 机制上存在问题,Android 7.0+ 才能 ok,早期的内核下会导致英文 fallback 到 Noto Sans Myanmar,这个字体非常丑。

  2. 针对 MIUI 8.0+设备:
    设置 font-family: miui 。这个方案就是显式申明中文的方案,MIUI 在 8.0+上内置了小米兰亭,同时在 fonts.xml 里给这个字体指定了family name:miui,所以我们可以直接设置。

  3. 添加 border 相关属性:

1
2
border: 1px solid transparent;
box-sizing:border-box;

后来的 CSS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.btn {
  font-family: sans-serif;
  width: 1.46rem;
  font-size: 0.28rem;
  height: 0.56rem;
  line-height: 0.56rem;
  border-radius: 0.56rem;
  background: #fedc53;
  color: #6e3d00;
  text-align: center;
}