最近手机端测移动网页,偶然发现,iOS下访问都正常的页面,Android下微信内嵌浏览器、自带浏览器等都正常,唯独手机QQ内嵌浏览器下显示略不正常,比如设置了16px字体,看起来明显没有16px,而网页部分元素是由行高撑起的,没有固定高度。于是,正常的页面在QQ内嵌浏览器中显示出现没有垂直居中、元素高度缩小等。

一开始以为是兼容问题,简单搜了下,只有看到知乎上有人问类似问题,感觉有点不可思议,感觉这么”大”的问题不可能没人发现,于是就怀疑自己的写法是否有问题,首先打开页面时,在界面上打出某元素的font-size,结果,和设置的值14px相差甚远,算了一下,只有设置像素的79%。没办法,就把原先没有固定高度的元素按照正常设备上最终显示的高度设置了固定高度,字体设置行高为1,采用padding或者margin实现垂直居中,这样以来,虽然字体小点,高度小点,但至少设计的垂直居中效果在QQ内置浏览器中显示基本正常了。期间,也尝试通过js动态改变根元素的字体的方式,基本恢复了设计的界面效果,但还是感觉怪怪的,最终没有采用。

今天偶然想起来,个人有个癖好,电脑、手机什么的都设置最小图标、最小字体,刚买手机那会貌似给系统设置了小字号,难道是这个原因引起的?果断调整系统字体,重新打开问题页面,居然就这样正常了,原来纠结了一晚上的问题竟然是因为手机设置的原因。所以,这个问题归根结底就不算是问题了。

不过好奇的是,微信及其他软件都没有影响,唯独QQ内嵌浏览器下影响,到底应用软件该不该取系统字体随之改变呢?是QQ太遵守标准了还是其他软件不按常规出牌呢?这个也不得而知了。简单记录一下,方便遇到类似问题的同学不绕弯路。

2017.4.20更新

前期因为没有使用rem作为移动端样式单位,后面为了简单的适配ipad等,通过gulp脚本将px转换为了rem,并且加入了淘宝那套lib-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;
}

refreshRem函数内部设置fontSize之后通过getComputedStyle获取计算后的值,然后根据比例计算实际应设置的root em大小,然后重新赋值即可,如此完美解决了Android手机环境下出现的各种字体不对的情况。另外有朋友遇到这样的问题,给他大概描述过之后,他曾修改lib-flexible并提交PR,但截至更新文章,并未合并。