聊一聊rem

作者: 赵Wayne | 来源:发表于2021-03-04 18:05 被阅读0次

    我们还是老惯例从三个方面,为什么,是什么,怎么做来剖析一个问题

    【为什么】

    首先讲几个知识点,根本原因需要一些基础知识才能了解透彻

    物理像素:

    一个设备生产出来,他们的像素就已经确定了,比如iphone5的分辨率是640*1136px,那么水平方向上有640个像素点,竖直方向上有1136个像素点。用放大镜可以肉眼看到多少个四方块,这些四方块就是物理像素。四方块的大小是不会变化的。


    image.png
    逻辑像素:

    也叫设备独立像素或css像素,他的单位也是px,CSS像素是Web编程的概念

    设备像素比(Device Pixel Ratio):

    DPR = 物理像素 / 逻辑像素

    很多年前我们的技术没那么发达,电脑和手机都是单像素的,也就是一个物理像素点(四方块)可以放一个css像素,但是随着技术的发展一个物理像素点(四方块)可以放置四个css像素,甚至更多越多越清晰人眼看的时候。一般的win电脑DPR=1,Mac的DPR=2,iPhone的DPR=2,安卓手机DPR那就很魔鬼了从1到3都见过甚至还MD有小数点。
    1.在JavaScript中,通过window.devicePixelRatio来获取
    2.在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同DPR的设备,做一些样式适配


    image.png

    这是同一个网址alert(window.devicePixelRatio)的结果


    image.png
    所以说了这么多的基础知识点就是为了告诉你为什么原来同样的16px(css像素)的在DPR为1的设备上看的还行但是换成DPR=2或者等于N的设备的话就会变小,因为同样16px占DPR=1的设备16个方块(物理像素),占DPR=2的8个方块(物理像素),占DPR=4四个方块(物理像素)....
    所以REM出来就是解决这个问题的!

    【是什么】

    rem它是CSS3中新增加的一个尺寸(度量)单位,全称font size of the root element,所以他出来时候就是一个字体的单位,而且是相对于根元素(html)的单位,对于元素的宽高不建议用,但是也可以用。
    这个单位可谓集相对大小em和绝对大小px的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。

    知识点:浏览器的默认字体是16px,所以给html设置font-size=62.5%也就是改变下默认根元素的字体为10px, 然后1rem就等于10px,其实就是为了计算方便。

    rem的原理:
    (1)本质其实就是等比缩放
    (2)clientWidth/UI图宽度 这个是缩放比

    【怎么做】

    下面是简单的做法,发现不能真正实现不同尺寸手机或者浏览器的等比例,所以弃用
    html{
    font-size: 62.5%;
    }

    正确的应该使用JS去监听尺寸再去等比例转化,rem.js有好多种版本可以望网上自行搜索,我测试了一下两种,更倾向于第二种。

    正确的步骤为:

    (1)//引入 meta

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

    (1)添加js

    //第一种可行(但是会延迟才执行)
    // window.onload = function(){
    //     //750代表设计师给的设计稿的宽度,你的设计稿是多少
    //     //下面的10就是一个比例,10px=1rem
    //     getRem(750,10)
    // };
    // window.onresize = function(){
    //     getRem(750,10)
    // };
    // function getRem(pwidth,prem){
    //     var html = document.getElementsByTagName("html")[0];
    //     var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
    //     html.style.fontSize = oWidth/pwidth*prem + "px";
    // }
    // //第二种(不会延迟)
    !function(n){
        var  e=n.document,
             t=e.documentElement,
            //750是设计师给的一般设计稿的宽度iphone7 和ihpneX
            //下面的20就是一个比例,20px=1rem,  这样你设计稿是多少100px那就是10rem,因为设计稿根手机存在一个二倍的关系,手机一般DPR是2 。
             i=750,
             d=i/20,
             o="orientationchange"in n?"orientationchange":"resize",
             a=function(){
                 var n=t.clientWidth||320;n>750&&(n=750);
                 t.style.fontSize=n/d+"px"
             };
             e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
    }(window);
    
    image.png

    全部测试代码

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
      <title>rem</title>
    <style>
      *{
        margin: 0;
        padding: 0;
      }
    /*  html{
        font-size: 62.5%;
      }*/
      body{
        height: 100vh;
        background-color: #ccc;
      }
     .header{
        height: 4rem;
        width: 100%;
        text-align: center;
        line-height: 4rem;
        background-color: red;
        font-size: 3rem;
     } 
     .iconWarp img{
      width: 100%
     }
     .main{
        display: flex;
        justify-content: space-around;
        padding-top: 1rem;
        padding-bottom: 1rem;
     }
     .iconWarp{
        width: 12%;
        text-align: center;
     }
     .iconWarp p{
      font-size: 2rem;
     }
     .banner{
      width:100%
     }
    </style>
    </head>
    <body>
    
    <div class="header">首页</div>
    <img class="banner" src="http://pic.zjk169.net/Uploads/Picture/2021-02-09/6021f09f71d83.jpg">
    <div class="main">
       <div class="iconWarp">
         <img src="http://mm.zjk169.net/static/img/icon1.png">
         <p>新房</p>
       </div>  
       <div class="iconWarp">
         <img src="http://mm.zjk169.net/static/img/icon2.png">
         <p>新房</p>
       </div>
       <div class="iconWarp">
         <img src="http://mm.zjk169.net/static/img/icon3.png">
         <p>新房</p>
       </div>
       <div class="iconWarp">
         <img src="http://mm.zjk169.net/static/img/icon4.png">
         <p>新房</p>
       </div>
       <div class="iconWarp">
         <img src="http://mm.zjk169.net/static/img/icon5.png">
         <p>新房</p>
       </div>
    </div>
    <div>
      
    </div>
    </body>
    <script type="text/javascript">
    
    //第一种可行(但是会延迟才执行)
    // window.onload = function(){
    //     //750代表设计师给的设计稿的宽度,你的设计稿是多少
    //     //下面的10就是一个比例,10px=1rem
    //     getRem(750,10)
    // };
    // window.onresize = function(){
    //     getRem(750,10)
    // };
    // function getRem(pwidth,prem){
    //     var html = document.getElementsByTagName("html")[0];
    //     var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
    //     html.style.fontSize = oWidth/pwidth*prem + "px";
    // }
    // //第二种(不会延迟)
    !function(n){
        var  e=n.document,
             t=e.documentElement,
            //750代表设计师给的设计稿的宽度,你的设计稿是多少
            //下面的20就是一个比例,20px=1rem
             i=750,
             d=i/20,
             o="orientationchange"in n?"orientationchange":"resize",
             a=function(){
                 var n=t.clientWidth||320;n>750&&(n=750);
                 t.style.fontSize=n/d+"px"
             };
             e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
    }(window);
    </script>
    </html>
    

    相关文章

      网友评论

        本文标题:聊一聊rem

        本文链接:https://www.haomeiwen.com/subject/ncrkqltx.html