相信做前端开发的朋友很多时候会遇到这样的问题,设置行高来达到文本垂直居中的目的,但移动端会遇到略偏上或者偏下,通常情况下轻微的偏移可能出现于设备像素密度、容器高度、字体大小等原因,比如30px容器内放15px文字,就做不到完全居中,这个不在今天问题范围,不再赘述。

今天的问题其实算是旧事重提,遇到这个问题,最初是在2015年了,当时团队其他同事做混合app有类似问题,同事最终似乎是采用padding的形式取代了行高,但实际上这个还会引起一些问题,主要是Android系统设置字体后,WebView内字体大小深圳和字体相关的属性都受到影响。

在去年4月份曾写过一篇文章《QQ内置浏览器下网页行高、字体大小显示异常解决》,但是当时只注意到Android系统下手机QQ内嵌的浏览器,直至后期做自己的Android App使用WebView内嵌网页,也发现了同样的问题,经过翻阅网上资料案例,发现近期挺多类似文章和提问,主要原因是Android系统多使用sp作为单位,会根据用户设置缩放字体。

常规的解决方法主要有以下两种

1、针对原生App,onCreate、onRestart都加上以下两行代码

DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
displayMetrics.scaledDensity = displayMetrics.density;

2、针对WebView

WebSettings webSettings = webView.getSettings();
webSettings.setTextZoom(100);

方法1做到的是类似微信的,整个App字体都不受系统影响。本文主题是Web,所以如果我们是纯粹的混合App,可以采用方法2直接设置禁止缩放。如果我们只是做Web开发,可能希望在手机QQ、自己App内嵌等情况下都正常,同时我们又只能从Web端着手,那么建议使用整站rem的形式,比如使用淘宝的flexible,但是flexible也是没有解决这个问题,所以我们自己对flexible做一些小小的改动。

前面文章有贴过的一段代码,重复贴一下

function refreshRem() {
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr > 540) {
        width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    var computedFontSize = parseFloat(win.getComputedStyle(docEl).fontSize);
    if (rem !== computedFontSize) {
        rem = +(rem * rem / computedFontSize).toFixed(4);
        docEl.style.fontSize = rem + 'px';
    }
    flexible.rem = win.rem = rem;
}