移动端兼容之彻底弄懂如何设置 rem

    技术2022-07-13  70

    前言

    众所周知,rem 是相对根元素的单位,而 em 是相对父级元素的,前者减少了层级关系的换算,使计算更准确,方便我们使用。

    移动端兼容,还得看 rem !

    具体如何设置呢?这里提供四大方法,按需取用。原理一致,一通百通。如果只是为了用而用,Duck 不必。

    正文

    62点5法

    通常情况下:因为各浏览器默认字体字号为 16px,即 16px 相当于 1rem ,应当设置如下:

    html, body { font-size: 16px; /*default font-size equal 1 rem*/ } h1 { font-size: 1rem; /*16px * 1 = 16px*/ } h2 { font-size: .8rem; /*16px * 0.8 = 12.8px*/ }

    但是显然,这样设置会造成换算的麻烦,因为要除以16。如何使得 1rem = 10px 呢? 我们可以定义 10px / 16px = 0.625 = 62.5% ,即浏览器的默认字体为 16px * 62.5% = 10px。

    设置如下:

    html, body { font-size: 62.5%; /* 10px / 16px = 62.5% 即 font-size 是 10px 相当于 1rem */ } h1 { font-size: 1rem; /*10px * 1 = 10px*/ } h2 { font-size: 1.2rem; /*10px * 1.2 = 12px*/ } h2 { font-size: 1.4rem; /*10px * 1.4 = 14px*/ }

    如果是 640px 的设计稿,需要除以 2(这个值是设备的 dpr) 转化为和 iphone5 屏幕等宽的320px。

    则把设计稿 px 值除以2,再除以10,即转为 rem 的值。

    之后再媒体查询设置每个屏幕大小的根的 font-size 百分比,页面会根据设置的根 font-size 适配。

    即如下伪代码:

    html,body{ (clientWidth / 320) * 62.5% }

    优:有一定适用性,换算也较为简单。

    劣:有兼容性问题,对不同手机适配不是非常精准;需要设置多个媒体查询来适应不同手机,单某款手机尺寸不在设置范围之内,会导致无法适配。

    625法

    上面提到的62点5大法是最通常的解决方案,适用大多数情况,但仍有特殊兼容性情况需要考虑。

    如:chrome 强制字体最小值为 12px,低于 12px 按 12px 处理,那上面的 1rem=10px 就变成1rem=12px,就会出现偏差。

    如何解决?十倍扩大百分比的设置即可,可称之为 625法。

    设置如下:

    html, body { font-size: 625%; // 使得1rem =100px,减少偏差情况的出现 }

    基准值法

    假设设计师给的稿是 750 ,基于 ip6(dpr 为 2)。 则可以设置基准值为 100; 即 1rem=100px。那么整体屏幕就是 7.5 rem。body 值为7.5 rem 不变,来倒推 px 的值。

    css换算和这个基准值有关;页面动态font-size值 = 屏幕宽度 / 设计稿 rem 宽度

    注:这里一定要考虑 dpr 这个变量,要先除掉。

    // iphone6: 宽度为 375 px,公式:375/7.5=50 html{font-size:50px} // iphone5:宽度为 320 px,公式:320/7.5=42.6667 html{font-size:42.6667px}

    优:通过动态根font-size来做适配,基本无兼容性问题,适配较为精准,换算简便。

    劣:无viewport缩放,且针对iPhone的Retina屏没有做适配,导致对一些手机的适配不是很到位。

    flexible 法

    这是手淘方案amfe/lib-flexible

    拿到设计稿除以10,得到font-size值。

    假设拿到的设计稿也是750,Flexible会把设计稿分为10份,可以理解为整个屏幕就是 10 rem,即1rem=75px,所以根的font-size=75px。

    引入 flexible.js

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <script src="./node_modules/amfe-flexible/index.js"></script>

    页面不用再设定 。Flexible会自动设定每个屏幕宽度的根font-size、动态viewport、针对Retina屏做的dpr。

    优:通过动态根font-size、viewpor、dpr来做适配,无兼容性问题,适配精准(动态计算 viewport 和针对 iphone 手机的 dpr 缩放调整,使得页面适配更加精确)。

    劣:需要根据设计稿进行基准值换算,在不使用sublime text编辑器插件开发时,单位计算复杂。

    总结

    举例来说,移动端通常给的设计稿是750px,以 iphone6 为基准,iphone 6是 375px 乘以 2,这个 2 是dpr,也就是我们通常说的 2 倍屏。

    因为 rem 是相对单位,我们想着把设计稿宽度分为几份。假设是分成 10 rem,即整个屏是 10 rem,那么,倒推根元素设置的 font-size 应该是多大即可,基准大法和 flexible大法都是类似的思路。不过后者借助 flexible.js 可以更好地支持缩放和对 dpr 的支持(引入的文件已经帮你做了更详细的换算设定)。

    Processed: 0.010, SQL: 9