作者:hbxeagle
链接:github.com/hbxeagle/rem/blob/master/README.md

rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用。使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果。

rem 的官方定义『The font size of the root element.』,即以根节点的字体大小作为基准值进行长度计算。一般认为网页中的根节点是 html 元素,所以采用的方式也是通过设置 html 元素的 font-size 来做屏幕适配,但实际情况真有这么简单吗?

首先我们来看看使用 rem 实现手机屏幕适配的常用方案。

以设计稿的宽度为640px,即:designWidth = 640,同时设定在640px屏宽下 1rem=100px ,即:rem2px = 100。

设置 1rem=100px 的优点不言而喻。前端开发者在切图、重构页面的时候,通过直接位移小数点的方式,就可以将UI图中测量到的 px 值换算成对应的 rem 值,方便快捷。

此外,在 head 中我们还设置了:<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
viewport 的作用很重要,但不是本文的重点所以不展开,有兴趣的同学可以自行搜索。

先来看看具体方案:

下面四个方案来自同事共享,原理都是采用等比缩放的方式 —— 获得目标屏幕宽度和设计稿宽度的比,作为 rem 的基值(缩放系数),设置为html标签的字体大小。不同的只是在于性能取舍和书写习惯。

方案1

@media screen and (min-width: 320px) {html{font-size:50px;}}
@media screen and (min-width: 360px) {html{font-size:56.25px;}}
@media screen and (min-width: 375px) {html{font-size:58.59375px;}}
@media screen and (min-width: 400px) {html{font-size:62.5px;}}
@media screen and (min-width: 414px) {html{font-size:64.6875px;}}
@media screen and (min-width: 440px) {html{font-size:68.75px;}}
@media screen and (min-width: 480px) {html{font-size:75px;}}
@media screen and (min-width: 520px) {html{font-size:81.25px;}}
@media screen and (min-width: 560px) {html{font-size:87.5px;}}
@media screen and (min-width: 600px) {html{font-size:93.75px;}}
@media screen and (min-width: 640px) {html{font-size:100px;}}
@media screen and (min-width: 680px) {html{font-size:106.25px;}}
@media screen and (min-width: 720px) {html{font-size:112.5px;}}
@media screen and (min-width: 760px) {html{font-size:118.75px;}}
@media screen and (min-width: 800px) {html{font-size:125px;}}
@media screen and (min-width: 960px) {html{font-size:150px;}}

方案2

@media screen and (min-width: 320px) {html{font-size:312.5%;}}
@media screen and (min-width: 360px) {html{font-size:351.5625%;}}
@media screen and (min-width: 375px) {html{font-size:366.211%;}}
@media screen and (min-width: 400px) {html{font-size:390.625%;}}
@media screen and (min-width: 414px) {html{font-size:404.2969%;}}
@media screen and (min-width: 440px) {html{font-size:429.6875%;}}
@media screen and (min-width: 480px) {html{font-size:468.75%;}}
@media screen and (min-width: 520px) {html{font-size:507.8125%;}}
@media screen and (min-width: 560px) {html{font-size:546.875%;}}
@media screen and (min-width: 600px) {html{font-size:585.9375%;}}
@media screen and (min-width: 640px) {html{font-size:625%;}}
@media screen and (min-width: 680px) {html{font-size:664.0625%;}}
@media screen and (min-width: 720px) {html{font-size:703.125%;}}
@media screen and (min-width: 760px) {html{font-size:742.1875%;}}
@media screen and (min-width: 800px) {html{font-size:781.25%;}}
@media screen and (min-width: 960px) {html{font-size:937.5%;}}

方案3

var designWidth = 640, rem2px = 100;
document.documentElement.style.fontSize =  ((window.innerWidth / designWidth) * rem2px) + 'px';

方案4

, rem2px = ;
document.documentElement.style.fontSize =
  ((((window.innerWidth / designWidth) * rem2px) / ) * ) + '%';

为了更避免理解上的混乱,我在上面js的代码中加了 ( ) ,实际代码中是不需要的。详细分析一下,rem 和 px 直接的转换公式可以写为:

1rem = 1 * htmlFontSize
htmlFontSize 为 html 元素的字体大小。

首先来看方案1中,在屏宽为640px情况下的设置:

@media screen and (min-width: 640px) {html{font-size:100px;}}

可以很明显的表现出这一点 1rem = 1 * 100px ,同我们最初的设定。那么我们要得到其它屏幕大小的 htmlFontSize 值要怎么办。很简单如方案3,因为我们的采用等比缩放的方式适配,所以计算目标屏幕宽度和设计稿的宽度的比即可:

window.innerWidth / designWidth * rem2px + 'px'

由于浏览器默认字体大小为 16px,所以当我们使用百分比作为根节点 html 的字体大小时,即html元素的font-size值设置为一个百分比值,rem 的计算方式就会改为:

defaultFontSize = 16px
1rem = 1 * htmlFontSize * defaultFontSize

如方案2中,在屏宽为640px情况下的设置:

@media screen and (min-width: 640px) {html{font-size:625%;}}

应用上面的公式:

1rem = 1 * 625% * 16px
其中:625% * 16 = 6.25 * 16 = 100
所以:1rem = 1 * 100px

同样的可以得到所有屏幕大小下,html 的 font-size 值的计算公式,即为方案4:

window.innerWidth / designWidth * rem2px / 16 * 100  + '%'

DEMO屏幕旋转,最终多终端的解决方案为: 用% 显示来布局

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
    <script>
        window.onresize = function () {
            adaptRem()
        };
        window.onload = function () {
            adaptRem()
        };
        function adaptRem() {
            var head = window.document.getElementsByTagName('head')[0];
            var tdiv = window.document.createElement('div');
            var screenw = window.innerWidth || document.body.clientWidth;
            var defaultFontSize = 0;
            var adaptFontSize = 0;
            var tstyle;
            tdiv.style.width = '1rem';
            tdiv.style.display = "none";
            head.appendChild(tdiv);
            defaultFontSize = parseFloat(window.getComputedStyle(tdiv, null).getPropertyValue('width'));
            tdiv.remove();
            adaptFontSize = screenw / 20 - defaultFontSize + 100 + "%";
            document.documentElement.style.fontSize = adaptFontSize;
            tstyle = document.createElement('style');
            tstyle.innerHTML = "@media screen and (min-width: " + screenw + "px) {html,body{font-size:" + adaptFontSize + ";}}";
            tstyle.setAttribute('id', 'adapt');
            if (document.getElementById('adapt')) {
                document.getElementById('adapt').remove();
            }
            head.appendChild(tstyle);
        }
    </script>
</head>
<body>
你好,世界!
</body>
</html>

了解真实的『REM』多终端屏幕适配的更多相关文章

  1. 了解真实的『REM』手机屏幕适配

    rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...

  2. 真实的『REM』手机屏幕适配

    rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...

  3. 01-02 Flutter仿京东商城项目 功能分析、底部导航Tab切换以及路由配置、架构搭建:(Flutter仿京东商城项目 首页布局以及不同终端屏幕适配方案)

    Flutter和Dart交流学习群:交流群:452892873 01Flutter仿京东商城项目 功能分析.底部导航Tab切换以及路由配置.架构搭建 02Flutter仿京东商城项目 首页布局以及不同 ...

  4. 『REM』手机屏幕适配

    function adapt(designWidth, rem2px){ var d = window.document.createElement('div'); d.style.width = ' ...

  5. [C#]『CountdownEvent』任务并行库使用小计

    System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定. CountdownEvent  专门用于以下情况:您必须使用 ...

  6. 在Ubuntu 11.10工具栏上用数字显示网速、CPU负荷和内存占用量『译』

    基本上照抄了<How To Display Network Upload / Download Speed On The Panel In Ubuntu 11.04>,只不过我的实践环境是 ...

  7. 了解真实的rem手机屏幕适配

    rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...

  8. 『计算机视觉』Mask-RCNN_从服装关键点检测看KeyPoints分支

    下图Github地址:Mask_RCNN       Mask_RCNN_KeyPoints『计算机视觉』Mask-RCNN_论文学习『计算机视觉』Mask-RCNN_项目文档翻译『计算机视觉』Mas ...

  9. 『计算机视觉』Mask-RCNN_训练网络其二:train网络结构&损失函数

    Github地址:Mask_RCNN 『计算机视觉』Mask-RCNN_论文学习 『计算机视觉』Mask-RCNN_项目文档翻译 『计算机视觉』Mask-RCNN_推断网络其一:总览 『计算机视觉』M ...

随机推荐

  1. 廖雪峰Java13网络编程-3其他-2RMI远程调用

    1.RMI远程调用: Remote Method Invocation 目的:把一个接口方法暴露给远程 示例: 定义一个接口Clock,它有一个方法能够获取当前的时间,并编写一个实现类,来实现这个接口 ...

  2. 【UVa 12186】Another Crisis

    [Link]: [Description] 给你n个员工和一个boss; 这n个员工和boss之间的关系是一棵树; 然后,现在最底层的叶子节点,想要向上级写信; 每个叶子节点都会向上级写一封信; 然而 ...

  3. input判断输入值是否合法

    1.判断input输入的值是否合法有很多办法,我这里使用的是在onchange时进行判断,代码如下:[所有主要浏览器都支持] <input type="text" name= ...

  4. DRF 序列化组件单增

    目录 自定义序列化(矬) Serializer类(方式繁琐) 底层序列化类 UserSerializer 视图序列化步骤 底层反序列化类 UserCreatSerializer 视图反序列化步骤 Mo ...

  5. 大O法时间复杂度计算

    困惑的点——log,如何计算得出? ① 上限:用来表示该算法可能有的最高增长率. ② 大O表示法:如果某种算法的增长率上限(最差情况下)是f(n),那么说这种算法“在O(f(n))中”.n为输入规模. ...

  6. 《DSP using MATLAB》Problem 8.12

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  7. python 中动态类的创建

    参考 collections.namedtuple 的实现 链接: https://www.cnblogs.com/BeautifulWorld/p/11647198.html

  8. 路飞学城-Python爬虫集训-第一章

    自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...

  9. GitHub的使用问题记录

    1. github如何收藏和关注? github 中的star作用:star 的作用是收藏,目的是方便以后查找. watch 的作用是关注,目的是等作者更新的时候,你可以收到通知.fork 的作用是参 ...

  10. Leetcode134. Gas Station加油站

    在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升.你从其中的一个加 ...