在根据 UI 给的两倍高保真图写前端页面时发现,页面的根元素字体尺寸是动态变化的。选择不同的模拟设备(emulated devices),font-size 的数值还会发生变化。

<html style="font-size: 19.0678px;">
...

发现这个问题是因为某个元素设置了 border-radius: 50% 在不同的设备下发生了形变。查看后发现,之前只设置了宽度,显示正常,改变模拟的设备后,rem 宽度拉伸,导致外框不再呈现为圆形。

之前了解过 rem 的特性:px、em、rem 的区别介绍。在设置了 html 根节点的 font-size 之后,其他的元素只要设置一个相对值(rem)就可以统一尺寸了,包括字体大小。设置唯一的 html font-size 可以确保元素在任何的设备上大小表现一致,缺点是手机上的应用放到 pad 上会很丑。而根据不同的设备,设置不同的 html font-size 值可以对应用在不同的设备上的显示做微调,以适配设备本身。

两者各有优缺点,考虑到 destoon 做应用的专业性和自己前端的不专业,还是暂时保留其动态调节 html 字体的功能。字体大小还是按照 html font-size 16px 的标准去写。好奇是怎么实现字体适配的,就去尝试定位其适配根节点字体的方法。最终找到了两种方法,一种是通过 js 适配,另一种是通过 css media 媒体查询适配。

通过 js 修改元素样式大致有以下三种方法:

// 1.原生Js法
var a = document.getElementById("a");
a.style.display="block";
// 2.用JQuery的css方法
var a =$("#a");
a.css("display","block");
// 3.用JQuery的attr方法
var a =$("#a");
a.attr("style","display:block");

最终找到 js 修改根节点字体大小的地方:

    var docEl = document.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        recalc = function() {
            //设置根字体大小
            let maxWidth = 750;
            let cw = docEl.clientWidth>maxWidth ? maxWidth : docEl.clientWidth;
            docEl.style.fontSize = 12 * (cw / 236) + 'px';
        };

    window.addEventListener(resizeEvt, recalc, false);
    document.addEventListener('DOMContentLoaded', recalc, false);

其中根节点字体大小的计算公式不知道出自何处,作用大致是监测屏幕宽度变化,然后通过公式得到当前根节点字体大小并设置。

css media 设置的方式比较熟悉:

@media only screen and (min-width:400px){html{font-size:21.33333333px !important}}
@media only screen and (min-width:414px){html{font-size:21px !important}}
@media only screen and (min-width:480px){html{font-size:25.6px !important}}

因为加了强制设置,所以我自己文档里的设置样式被覆写了,这也是我发现这一方法的原因。这里面 media 适配的宽度比正常的手机稍微大了那么一些,对于 iphone 7/8/9/x 这样屏幕宽度(375px)小于 400px 的真正起作用是上面的 js 设置方式。

[notice]rem 只相对于根节点的 font-size 计算,也就是 html 标签的 font-size 属性,body 设置只能影响没有设置字体大小的标签内文字。[/notice]

        html {
            font-size: 16px!important;
        }
        @media only screen and (max-width: 320px){html{font-size:13px;}}
        /*@media only screen and (min-width: 321px) and (max-width:400px){html{font-size:16px;}}*/
        /*@media only screen and (min-width: 400px){html{font-size:18px;}}*/
        @media only screen and (min-width: 414px){html{font-size:19px;}}
        @media only screen and (min-width: 480px){html{font-size:25.6px;}}

以上是我调整使用的字体大小,以 16px 作为默认根节点字体大小,适配 iphoneX 375px 屏幕宽度,19px 对应 plus 型号,13px 对应 iphone5/SE 型号。

综合这两种方式理解一下 destoon 移动端字体适配机制。对于移动端大尺寸(400px 以上)的屏幕,修改根节点字体大小以达到最佳效果;对于中小尺寸的屏幕,使用浏览器默认的根节点字体大小(应该是 16px,也是我参照的尺寸)。js 的适配方法明显是后续添加的,destoon7 源码里并未发现,所以应该是后续开发对中小尺寸的适配。

为统一设置标准,可以在 js 和 media 之间二选一,然后再设置默认的根节点字体大小。现有的应用中引入的 aui.2.0.css 样式表, 里面根节点字体大小设置为 20px,其实都可以,只不过我这边已经按照 16px 进行计算了,统一设置就行。