动态rem

作者: sunny519111 | 来源:发表于2017-07-07 11:40 被阅读145次

    layout 和 screen的宽度

    在比较遥远的时候,网页还是在pc端流行,很少有人开发移动端网页,所有网页的宽度比较大。 随着移动端开发的慢慢崛起,我们就想把pc端的页面放到移动端也能正常的查看,但是手机屏幕那么小,怎么才能完全的显示整个页面的布局呢?

    我们通过手机浏览器打开网页,尽然手机屏幕的大小改变不了,那么有没有一种办法,让手机浏览器的内部宽度变得和pc端的大小相近呢?浏览器的厂商开始发现了这个商机,纷纷的开始开发,终于达成了,在一般情况下,手机浏览器的内置宽度是980px。这样,我们用手机浏览器打开pc端的页面也可以看了,但是需要用户滚动和缩放才可以清除的查看网页,但是作为一个开发人员,对用户这么不友好,饭碗都没有了。

    // iphone 7
    document.documentElement.clientWidth  // 980px
    screen.width // 375px
    

    上面提到了2个宽度,屏幕宽度(visual width)和手机浏览器内部宽度(layout width)


    1.png

    之后出现了<meta name='viewport>可以进行设置和开发, 下面再探讨。

    通过meta改变layout width

    我们从上面知道,如果不设置,浏览器默认的layout width的值是980px,但是我们在移动端开发的时候,不希望用户非要通过方法页面和滚动页面来展示内容,有没有一种方法,让我们的在开发移动端页面的时候layout widthvisual width一样呢?这样我们设置的css的像素就会很清晰的反应在页面中。用户也可以不需要缩放的查看页面。

    这个时候meta标签就登场了。

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    

    通过上面代码layout width===visual width

    initial-scale缩放什么

    直接上公式:

    initial-scale = layout width(布局宽度) / visual width(视口宽度)
    

    我是这样理解的,如果我们设置了initial-scale = 0.5,意味着缩小一半,那应该是什么缩小呢? 通过测试,我得到是页面的元素缩小了,例如:本来10px可以展示30长度,现在要缩小一半,10px不能变,30长度也不能变,要让30长度在layout width中显示的区域缩小一半,只能是放大layout width了

    动态REM移动端方案

    1. 把html的font-size设置成设计稿的宽度

    <meta name="viewport" content="width=device-width ,initial-scale=1,maximum-scale=1,minimum-scale=1" >  <!--如果不设置width= device-width,则浏览器默认模拟的是980px-->
    <script>
      var css = `html{
        font-size: 320px
      }`    
      document.write(`<style>${css}</style>`)
    <script>  
    
    1. 设计稿页面的宽度 === 320px === html的font-size
    2. 1rem === html的font-size
    3. 由1和2 推出 1rem = 设计稿页面的宽度

    2. 根据设备的尺寸调正html的font-size

    把html的font-size*修改后的数据

    <meta name="viewport" content="width=device-width ,initial-scale=1,maximum-scale=1,minimum-scale=1" >  <!--如果不设置width= device-width,则浏览器默认模拟的是980px-->
    <script>
      var width = document.documentElement.clientWidth  //如果不设置宽度,浏览器默认模拟的是980px
      var scale = width/320;
      console.log(scale)
      var css = `html{
        font-size: ${320*scale}px
      }`    
      document.write(`<style>${css}</style>`)
    </script>  
    
    1. 实际页面的宽度 === ? === html的font-size
    2. 1rem === 实际页面的宽度

    3. 设置好font-size后根据比例换成rem

    统一根据自身尺寸/设计稿尺寸来设置rem

    1. 由于1rem=320px(设计稿尺寸) ,所有我们需要把对应的比例px变成rem
    2. 例如原来的16px的margin-top,变成现在的16/320rem 是不是觉得会变得很小,不方便计算,所以又有一个方案,统一的把html的font-size除以10,然后我们在转换的时候再乘以10
    <!-- 防止数据太小,统一变化下 -->
    <script>
      var width = document.documentElement.clientWidth  //如果不设置宽度,浏览器默认模拟的是980px
      var css = `html{
        font-size: ${width/10}px
      }`
      document.write(`<style>${css}</style>`)
    </script>
    
    <!--使用css函数来统一变化rem-->
    rem($px)
       ($px/320*10)rem
    
    <!-- 是不是好奇为什么不除以100,因为除以100的话,font-size=320/100 = 3.2px -->
    <!-- 3.2px???你想想浏览器的最小像素是多少?是多少?默认的是12px,你设置的话,最小也是6px,所以不行 -->
    

    4. 结尾

    到这里,其实已经做好了手机端的rem,但是由于设计师的职业病,就出现了border1px的小小小bug,你如果觉得1px不重要,到这里就可以了。下面我将要解析下设计师的处女座情节

    相关文章

    1. 腾讯rem
    2. 阿里巴巴UED
    3. 腾讯app-rem变革

    border-1px的问题

    这个问题的来源

    1. 人有富贫,屏幕也一样,好的屏幕的dpr是不同的,展示在我们面前的色彩,清晰度都是不一样的。
    2. retina屏幕下,dpr = 2或3,但是在普通的屏下面dpr=1
    苹果手机dpr.png

    dpr(设备像素比)

    devicePixelRatio = 物理像素 / 独立像素 
    // 我们的css中的px === 独立像素
    // 实际屏幕像素  ===  物理像素
    
    1. 首先我们手机的分辨率高,就看的东西越仔细,这是为什么呢? 分辨率和我们的dpr又有什么联系呢?

      在屏幕大小都差不多的情况下,一个分辨率为750的, 一个分辨率为640的手机,都要展示一个长度为30px的物体,让这个物体占有同样的面积,所以只有高分辨率(750)的1物理像素对应的独立像素多,也就是dpr高。不然的话,在同等dpr中,css的1px对应相同的物理像素,在750的分辨率中就会变小。

    2. 通过dpr,我们可以知道该设备上一个css像素代表多少个物理像素。例如,在Retina屏的iphone上,dpr的值为2,也就是说1个css像素相当于2个物理像素。

    3. 然后得说一下,为什么存在retina下,border: 1px这一说?

    我们正常的写css,像这样border: 1px;,在retina屏幕下,会有什么问题吗?

    设备像素比

    在retina屏幕下,我们设计师想要的1px,其实是1物理像素,但是对于css而言,只需要显示0.5px,但是在普通的屏下面的,css的0.5px会被默认的当成0px处理,这就是一个矛盾了。

    解决border 1px

    1. 通过windon.devicePixelRatio获取页面的设备像素比
    2. 通过<meta name="viewport" content="width=device-width ,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}" > scale来缩放比例
      var scale = 1 / window.devicePixelRatio; //获取对应的缩放比例
    3. 由于initial-scale的改变,引起了设备独立像素的改变,也就是document.documentElement.clientWidth的改变。第二步 把initial-scale变小了,引起了document.documentElement.clientWidth的变大对应的倍数,所以这一缩小,一放大就抵消了。
    4. 获取正确的document.documentElement宽度
    没有设置width=device-width.png
    <!-- 由于我们在meta中没有设置width=device-width 所以我们
      通过document.documentElement.clientWidth获取的宽度是物理像素 * dpr 
    -->
    <script>
      var scale = 1 / window.devicePixelRatio; //获取对应的缩放比例
      var meta = `<meta name="viewport" content="initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale} user-scalable=no">`
      document.write(meta);
      var width = document.documentElement.clientWidth 
      var css = `html{
    font-size: ${width / 10}px
    }`
      document.write(`<style>${css}</style>`)
    </script>
    

    最后链接

    芳姐线上浏览地址加上1px
    移动前端开发之viewport的深入理解

    相关文章

      网友评论

          本文标题:动态rem

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