移动端字体放大的解决方案

前言

正常情况下我们调整手机的字体大小,我们在webview中也会看到的效果也是被放大的,但是用了rem算法的内嵌页,字体也会随着变大,从而导致文本不居中、文字折行、布局混乱等问题。在此对字体放大的问题做一个笔记,下面列几条对字体放大有用的解决方案。

1.Meta设置

1
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

保持屏幕比例1:1 禁止缩放,但这里对字体无效

2.IOS解决方案

在iPhone系统设置中的“更大字体”里调整字号后,各个应用里中Webview里的文字大小似乎没有受到影响。但是对于诸如微信、UC浏览器等可以在APP里设置网页字体大小的应用,还是有限制调整字号的需求的。它们调整字体大小是通过给body设置-webkit-text-size-adjust属性实现的,因此只要限制这个属性不被修改即可:

1
2
3
body {
-webkit-text-size-adjust: none !important;
}

3.Android解决方案

  • 方案1(APP方法)

如果是在自己开发的APP中,可以在客户端的WebView组件中设置字体默认的缩放比例,以避免手机系统的字体修改对页面字体及布局造成影响。

1
2
WebSettings settings = webView.getSettings();
settings.setTextZoom(100);

  • 方案2(Android微信)

如果是在微信环境中,参考微信开放平台的文档,须通过WeixinJSBridge对象将网页的字体大小设置为默认大小,并且重写设置字体大小的方法,让用户不能在该网页下设置字体大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function() {
if (typeof WeixinJSBridge == "object" && typeof WeixinJSBridge.invoke == "function") {
handleFontSize();
} else {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", handleFontSize, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", handleFontSize);
document.attachEvent("onWeixinJSBridgeReady", handleFontSize);
}
}
function handleFontSize() {
// 设置网页字体为默认大小
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
// 重写设置网页字体大小的事件
WeixinJSBridge.on('menu:setfont', function() {
WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
});
}
})();

需要注意的是,这段代码在Android微信环境中会延时生效。如果预先设置字号大小不是“标准”,打开网页时页面会按照设置的缩放效果展示约1秒(等WeixinJSBridge对象初始化完成)后才调整到正常。这个时间差的问题目前暂时没有合适的解决方式,只能通过增加loading动画、延迟展示时间等方式来尽量消除用户的不适感

  • 方案3(webview/微信通用)

Android因为改变的是字体的大小,所以可以考虑将字体大小在设置的时候进行等比例缩小。例如,一个文字希望以10px来进行渲染,当webview被放大两倍时,此时font-size会变为20px。因此我们可以在取到这个放大比例之后,对原样式进行等比缩小,比如将原文字大小设置为5px,渲染的时候就变成了10px.

如果我们的页面字体大小都使用rem进行声明,那么我们就只需要在页面加载的时候根据缩放比例计算出html元素的字体大小即可!详见下方代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(function(){
var $dom = document.createElement('div');
$dom.style = 'font-size:10px;';
document.body.appendChild($dom);
// 计算出放大后的字体
var scaledFontSize = parseInt(window.getComputedStyle($dom, null).getPropertyValue('font-size'));
document.body.removeChild($dom);
// 计算原字体和放大后字体的比例
var scaleFactor = 10 / scaledFontSize;

// 取html元素的字体大小
// 注意,这个大小也经过缩放了
// 所以下方计算的时候 *scaledFontSize是原来的html字体大小
// 再次 *scaledFontSize才是我们要设置的大小
var originRootFontSize = parseInt(window.getComputedStyle(document.documentElement, null).getPropertyValue('font-size'));
document.documentElement.style.fontSize = originRootFontSize * scaleFactor * scaleFactor + 'px';
})();

因为这段代码中创建了一个元素,并放入了document.body中,所以不能放在head中运行。如果放在页尾运行的话,则有可能会产生闪烁的情况,因此最好的办法是将这段代码放在开始的地方

除了在Android webview以外,以上代码在 Android 微信中实测也有效,亲测可用!

结语

其实正常情况下,我们考虑常规操作就OK了,某些用户想放大字体看效果(估计是眼神不好),按理说我们的页面也要跟着放大并且布局不能乱掉(用户想要的结果),但事实上我们处理起来并不是一个布局的问题,得按设计来(牵扯太多,不想改)。但是产品、老板、用户不接受这样的错乱页面,我们没办法只能找解决方案,做一个都能接受的处理。

相关链接:
移动端字体放大问题的研究

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 前言
    1. 1.1. 1.Meta设置
    2. 1.2. 2.IOS解决方案
    3. 1.3. 3.Android解决方案
  2. 2. 结语
,