flexible.js字体大小诡异现象解析及解决方案
最近在做一个手机端页面时,遇到了一个奇怪的问题:字体的显示大小,与在CSS中指定的大小不一致。大家可以查看这个Demo(记得打开Chrome DevTools)。

就如上图所示,你可以发现,原本指定的字体大小是24px,但是最终计算出来的却是53px,看到这诡异的结果,我心中暗骂一句:这什么鬼!
随后开始对问题各种排查:某个标签引起的?某个CSS引起的?又或者是某句JS代码引起的。通过一坨坨的删代码,发现貌似都不是。我不禁又骂,到底什么鬼!不过中间还是发现了一些端倪:当页面中的标签数量或者文本数量大于某一个值,或者当CSS定义的字体大小落在某个区间时,这个问题才会被触发。而且字体变大后的值也随着原始定义的字体大小而改变。
然后自然就是各种搜索,终于有了新的发现。原来这个特性被称做「Text Autosizer」,又称「Font Boosting」、「Font Inflation」,是 Webkit 给移动端浏览器提供的一个特性:当我们在手机上浏览网页时,很可能因为原始页面宽度较大,在手机屏幕上缩小后就看不清其中的文字了。而 Font Boosting 特性在这时会自动将其中的文字字体变大,保证在即不需要左右滑动屏幕,也不需要双击放大屏幕内容的前提下,也可以让人们方便的阅读页面中的文本。
不过这个特性并不总是有必要的,还好在查到问题原因的同时,大家也讨论了对这个问题的一些处理方案:
- 手动指定
viewport width=320,这时 Font Boosting 不会被触发。(后边可以知道,这个说法不严谨,在其他设置均为默认值时,这一条才有效) - Font Boosting 仅在未限定尺寸的文本流中有效,给元素指定宽高,就可以避免 Font Boosting 被触发。
- 显然第 2 条方案是有缺陷的,文本内容不可能都指定宽高。不过还好,我们通过指定
max-height,(经 @Ovaldi 指正,只有min-height,min-width,max-widthmax-height有效) 也是可以的。比如body * { max-height: 999999px; }就可以无副作用的禁掉 Font Boosting 特性。当然,我觉得没必要使用通用选择器,用类似p { max-height: 999999px; }可能更好一些。
到这里,我们已经明白问题所在,并且也有解决方案了。但是有一个问题仍然困扰着我:当字体大于某一个值时(比如当不指定viewport width,手机屏幕width=320,字体大于等于82px时),这个 Font Boosting 就始终不会被触发。Chrome 是如何计算的,这其中的逻辑又是什么?
这一次问题解决起来就没有那么容易了,我先是各种搜索无果,然后自己人肉去试,慢慢找规律,但是发现变化不是线性的,看来这个公式还比较复杂。终于在今天被我发现了这篇文章:Chromium's Text Autosizer,彻底解释了我的疑问。
Font Boosting 具体的实现代码在 TextAutosizer.cpp 这个文件中可以看到,有兴趣的可以翻一下。
简单说来,Font Boosting 的计算规则伪代码如下:
multiplier = Math.max(1, deviceScaleAdjustment * textScalingSlider * systemFontScale * clusterWidth / screenWidth);
if (originFontSize < 16) {
computedFontSize = originFontSize * multiplier;
}
else if (16 <= originFontSize <= (32 * multiplier - 16)) {
computedFontSize = (originFontSize / 2) + (16 * multiplier - 8);
}
else if (originFontSize > (32 * multiplier - 16)) {
computedFontSize = originFontSize;
}
其中变量名解释如下,更具体的说明可以参考上边的两个链接。
originFontSize: 原始字体大小computedFontSize: 经过计算后的字体大小multiplier: 换算系数,值由以下几个值计算得到deviceScaleAdjustment: 当指定viewport width=device-width时此值为 1,否则值在 1.05 - 1.3 之间,有专门的计算规则textScalingSlider: 浏览器中手动指定的缩放比例,默认为 1systemFontScale: 系统字体大小,Android设备可以在「设备 - 显示 - 字体大小」处设置,默认为 1clusterWidth: 应用 Font Boosting 特性字体所在元素的宽度(如何确定这个元素请参考上边两个链接)screenWidth: 设备屏幕分辨率(DIPs, Density-Independent Pixels),如 iPhone 5 为 320
说了这么多,貌似只需要记住 p { max-height: 999999px; } 就OK了。。。-_-!!!
用 max-height: 100% 可能会更好一些。
WebKit 中应该有判断如果initial-scale=1时,不触发Font Boosting。
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 或 -->
<meta name ="viewport" content ="initial-scale=1, maximum-scale=1, minimum-scale=1">
flexible.js字体大小诡异现象解析及解决方案的更多相关文章
- 配合sublime使用flexible.js实现微信开发页面自适应
什么是flexible.js 是一个终端设备适配的解决方案.也就是说它可以让你在不同的终端设备中实现页面适配. 是一个用来适配移动端的javascript框架.根据宽度的不同设置不同的字体大小,样式间 ...
- hotcss.js Flexible 移动端适配在dpr=2和dpr=3出现的字体大小设置不正确问题.
这段时间一直在用hotcss做移动端适配,做了几个页面没有发现什么问题,后来老大要加快进度,我把项目分出一块给另一个同事做,她发现了一个问题就是字体在dpr=2,dpr=3,的设备上字体大小显示老是不 ...
- 改变字体大小实现自适应之js方案A
一.元素大小有两种写法 1.写结果:设计师给的移动端页面sketch设计稿一般是750px宽度,在sublime编辑器里,设置cssrem或rem-unit插件为56px的字体大小.做页面时,设计稿是 ...
- html页面控制字体大小的js代码
dom对象控制显示文章字体大小的js代码 <head> <script type="text/javascript"> function check(siz ...
- WebStorm 在 Mac 版本的基本设置,包括 ES6、Node.js、字体大小等
WebStorm 在 Mac 和 win 的设置有区别,便于以后用到快速查找,记之. 要设置先点击 WebStorm 字样如下图: 后点击 Preferences 字样如下图: 设置 es6 语法, ...
- 应用js改变问章字体大小
刚来公司的时候领导给分配的都是一些简单的简单的简单的.....任务 一次叫我把文章的字体大小变换功能写出来.在网上搜了很多都不管用!不过功夫不负有心人还是被我找到了!拿出来分享下! <scrip ...
- js控制手机端字体大小rem
//得到手机屏幕的宽度 let htmlWidth = document.documentElement.clientWidth || document.body.clientWidth; if(ht ...
- 【前端开发】禁止微信内置浏览器调整字体大小的方法js
微信webview内置了调整字体大小的功能,用户可以根据实际情况进行调节.但是很多移动端页面的开发都是使用rem作为单位的,字体大小改变以后,会出现页面布局错乱的情况,因此希望能够禁止微信的字体放大功 ...
- 用js判断屏幕的宽度,改变html字体大小用rem布局
if (document.documentElement.clientWidth > 600) {//页面宽度大于600px让其宽度等于600px,字体大小等于60px,居中 document. ...
随机推荐
- MySql 跟踪命令
SHOW ; SHOW FULL PROCESSLIST; ; USE table1; ; SHOW PROFILES; ; SHOW TABLES; SHOW PROFILES; SHOW PROF ...
- 动态绑定GridView数据源遇到问题
1.GridView中的Button控件响应Command事件的时候出现System.ArgumentException: 回发或回调参数无效, 设置<pages enableEventVali ...
- ajax请求参数为中文乱码的情况
解决中文乱码问题的方法有很多. 一.前提是ajax请求传递参数对象到后台,对象中的某个参数的值为中文,到后台之后出现乱码,导致报错.问题解决如下: rest层: 二.在tomcat的server.xm ...
- linux查看磁盘空间
首先如果需要查看整个磁盘还剩多少空间,可以使用命令: df -h 如果你并不关心磁盘还剩余多少空间,只是需要知道当前的文件夹下的磁盘使用情况,可以使用如下命令: -h 上面使用du --max-dep ...
- oracle表空间使用情况查询
1. 查看所有表空间大小 SQL> select tablespace_name,sum(bytes)/1024/1024 from dba_data_files 2 group by tabl ...
- jquery dataTable 入门
step1:切记要先引入jquery <link rel="stylesheet" type="text/css" href="C:\Users ...
- web api简单验证实现办法
需要使用WEBAPI,但是有验证问题没解决.后来参考网上文章做了一下DEMO 思路: 就是根据用户的账号在服务端加密一个字符串,然后返回给用户端. 具体: 一个用户编号用于唯一身份识别,密码,一个密钥 ...
- [转]hibernate主键生成策略
1.自动增长identity 适用于MySQL.DB2.MS SQL Server,采用数据库生成的主键,用于为long.short.int类型生成唯一标识使用SQL Server 和 MySQL 的 ...
- Linux下的正则表达式(基础)
grep -n 'the' text.txt 搜寻含有the的部分(n代表现实显示行号) grep -vn 'the' text.txt 搜寻不含有the的部分(n代表现实显示行号) grep -vn ...
- EF数据迁移(当模型改变时更新数据库)
https://msdn.microsoft.com/zh-CN/data/jj591621 Enable-Migrations Add-Migration 名称 Update-Database –V ...