zoukankan      html  css  js  c++  java
  • 等比缩放布局(rem布局)的实现

      rem的定义,the font size of the root element,即以根节点的字体大小作为基准值进行长度计算。网页中的根元素指的是html我们通过设置html的字体大小就可以控制rem的大小。

      视口(viewport)设置:<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />

      在html上根据不同分辨率设置不停font-size,通过js计算出来。

      页面里除了font-size之外的其他css尺寸都使用了rem作为单位。

      正文的font-size需要额外的媒介查询,并且不使用rem。

      要搞懂移动端的适配,首先要高明白像素和视口。

      其实存在两种像素:

      1. 设备像素

      屏幕的物理像素,任何设备屏幕的物理像素的数量都是固定不变的,单位是pt

      2. CSS像素

      在CSS、JS中使用的一个抽象的概念,单位是 px

    顺便说下,CSS像素也可以称为设备独立像素(device-independent pixels),简称为dips,单位是dp

      那么,我们现在再来说说一个元素 200px 。这个元素跨越了200个CSS像素,200个CSS像素相当于多少个设备像素取决于两个条件:

    • 页面是否缩放
    • 屏幕是否为高密度

      

      先梳理一下手机硬件之间的关系,注意这里使用的都是物理像素。

      以 iPhone5 为例,我们已知的是:

    1. 分辨率:1136pt x 640pt
      指屏幕上垂直有 1136 个物理像素,水平有 640 个物理像素
    2. 屏幕尺寸: 4英寸
      注意英寸是长度单位,不是面积单位。4英寸指的是屏幕对角线的长度。
    3. 屏幕像素密度:326dpi
      屏幕像素密度(Pibel Per Inch)简称 ppi ,单位是 dpi(dot per inch)。这里指屏幕水平或垂直每英寸有326个物理像素。原则上来说,ppi越高越好,因为图像会更加细腻清晰。

      ppi 是可以通过 分辨率 和 屏幕尺寸 计算得到的:ppi

      视口

      桌面浏览器中,浏览器窗口就是约束你的CSS布局视口(又称初始包含块)。它是所有CSS百分比宽度推算的根源,它的作用是给CSS布局限制了一个最大宽度,视口的宽度和浏览器窗口宽度一致。

      但是在移动端,情况就很复杂了。

      布局视口

      一个没有为移动端做优化的网页,会尽可能缩小网页让用户看到所有东西。

      浏览器厂商为了让用户在小屏幕下网页也能够显示地很好,所以把视口宽度设置地很大,一般在 768px ~ 1024px 之间,最常见的宽度是 980px。

      所以,在手机上,视口与移动端浏览器屏幕宽度不再相关联,是完全独立的,这个浏览器厂商定的视口被称为布局视口。

      布局视口我们是看不见的,只知道网页的最大宽度是 980px ,并且被缩放在了屏幕内。

      可以这样设置布局视口的宽度:<meta name="viewport" content="width=640">

      媒体查询与布局视口

      700px 指的是布局视口的宽度

      @media (min- 700px){
          ...
      }
      document.documentElement.clientWidth/Height返回布局视口的尺寸

      视觉视口

      视觉视口是用户正在看到的网页的区域,大小是屏幕中CSS像素的数量。

      window.innerWidth/Height返回视觉视口的尺寸

      理想视口

      布局视口明显对用户是不友好的,完全忽略了手机本身的尺寸。所以苹果引入了理想视口的概念,它是对设备来说最理想的布局视口尺寸。理想视口中的网页用户最理想的宽度,用户进入页面的时候不需要缩放。

      现在讨论所谓的『最理想的宽度』到底是多少?其实,如果我们把布局视口的宽度改成屏幕的宽度不就不用缩放了么。可以这样设置告诉浏览器使用它的理想视口:

      <meta name="viewport" content="width=device-width">

    定义理想视口是浏览器的事情,并不能简单地认为是开发者定义的,开发者只能使用。

      screen.width/height返回理想视口的尺寸,有严重的兼容性问题---可能返回两种值:

    1. 理想视口的尺寸(下载浏览器)
    2. 屏幕的设备像素尺寸(内置浏览器)
      缩放

      缩放与设备像素、CSS像素的关系

        缩放是在放大或缩小CSS像素,比如一个宽度为 200px 的元素放大,还是200个CSS像素。但是因为这些CSS像素被放大了,所以CSS像素也就跨越了更多的设备像素。缩小则相反。

       缩放与视口

      缩放会影响视觉视口的尺寸

      页面被用户放大,视觉视口内CSS像素数量减少;被用户缩小,视觉视口内CSS像素数量增多就行了。这个道理应该是不难想的。

      

    用户缩放不会影响布局视口

    注意,这是『用户缩放』,后面会说开发者设置缩放的情况

    缩放比例

    我们在开发者工具中可以在这里查看缩放比例:

    查看缩放比例

    这里的 0.3 是相对于理想视口的。

    在下载浏览器中,可以这么算(理想视口与视觉视口的比):

    zoom level = screen.width / window.innerWidth
    

    禁止缩放

    <meta name="viewport" content="user-scalable=no">
    

     

    设置缩放

    <meta name="viewport" content="initial-scale=2">
    

    使用initial-scale有一个副作用:同时也会将布局视口的尺寸设置为缩放后的尺寸。所以initial-scale=1width=device-width的效果是一样的。

    完美视口

    解决各种浏览器兼容问题的理想视口设置

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

       

    设备像素比

    在谈到像素的时候,讲到除了缩放,屏幕是否为高密度也会影响设备像素和CSS像素的关系。

    在缩放程度为100%(这个条件很重要,因为缩放也会影响他们)时,他们的比例叫做设备像素比(device pixel ratio):

    dpr = 设备像素 / CSS像素
    

    可以通过JS得到: window.devicePixelRatio

    设备像素比也和视口有关:

    dpr = 屏幕横向设备像素 / 理想视口的宽
    

    总结

    这一篇介绍了移动端适配需要掌握的知识,先说明了移动端存在的两种像素,然后介绍了三种视口,由缩放对视口的影响引入理想视口,最后说明设备想告诉比。

     之前做过PC页面的人聊的最多的就是『兼容』,这是因为浏览器之间的差异引起的,不再多说。而移动端是基本没有『兼容』的问题的,全是CSS3,简直不要太开心。可是『适配』问题随之而来。

    什么是『适配』?做PC页面的时候,我们按照设计图的尺寸来就好,这个侧边栏200px,那个按钮50px的。可是,当我们开始做移动端页面的时候,设计师给了一份宽度为640px的设计图。那么,我们把这份设计图实现在各个手机上的过程就是『适配』。

    那么,我们怎么开始呢?目前有三种方法:

    • 固定高度,宽度自适应
    • 固定宽度,viewport缩放
    • rem做宽度,viewport缩放

    这三种方法的核心都是视口的确定,现在以实现这个设计图为例说明。

    固定高度,宽度自适应

    demo

    这也是目前使用最多的方法,垂直方向用定值,水平方向用百分比、定值、flex都行。腾讯京东百度天猫亚马逊的首页都是使用的这种方法。

    随着屏幕宽度变化,页面也会跟着变化,效果就和PC页面的流体布局差不多,在哪个宽度需要调整的时候使用_响应式布局_调调就行(比如网易新闻),这样就实现了『适配』。

     

    原理

    这种方法使用了完美视口:

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

    这样设置之后,我们就可以不用管手机屏幕的尺寸进行开发了。

    固定宽度,viewport缩放

    demo

    设计图、页面宽度、viewport width使用一个宽度,浏览器帮我们完成缩放。单位使用px即可。

    目前已知荔枝FM网易新闻在使用这种方法。有兴趣的同学可以看看是怎么做的。

     

    原理

    这种方法需要根据屏幕宽度来动态生成viewport,生成的 viewport 基本是这样:

    <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">
    

    640 是我们根据设计图定下的,0.5 是根据屏幕宽度动态生成的。

    生成的viewport告诉浏览器网页的布局视口使用 640px,然后把页面缩放成50%,这是绝对的等比例缩放。图片、文字等等所有元素都被缩放在手机屏幕中。

    这个gif图说明了一切:

    1

    rem做宽度,viewport缩放

    demo

    这也是淘宝使用的方案,根据屏幕宽度设定 rem 值,需要适配的元素都使用 rem 为单位,不需要适配的元素还是使用 px 为单位。

    具体使用方法见使用Flexible实现手淘H5页面的终端适配

    上文提供了sass和postcss的px2rem转换方法,我这里给出less的px2rem。因为less不支持函数,所以需要安装插件 less-plugin-functions ,然后就简单了:

    .function{
        .px2rem(@px,@base:72px){
            return: @px / @base * 1rem;
        }    
    }

    这样使用:

    div{
         px2rem(100px);
    }
    

    使用这个方法的库:

     

    原理

    实际上做了这几件事情:

    1. 动态生成 viewport
    2. 屏幕宽度设置 rem的大小,即给<html>设置font-size
    3. 根据设备像素比(window.devicePixelRatio)给<html>设置data-dpr

    rem

    这么设置的好处是可以让不同设备的rempx都显示一样的长度。

    设置rem

    设置rem的意义在于得到一个与屏幕宽度相关的单位,本来vw是最合适的,但是因为兼容性的问题,只能使用rem来做。这样,让不同设备的rem显示一样的长度。

    vw是CSS3引入的单位,1vw = 1%窗口宽度

    rem

    上面的布局我们可以这样:

    html{
        font-size: 屏幕宽度 / 10; 
    }
    .btn{
        8.75rem;
        height:1.25rem;
    }

    这样,无论屏幕宽度是多少,.btn都是相对于屏幕的这么宽,做到了适配。

    设置 viewport 缩放 和 data-dpr

    这两个设置其实是干的一件事,就是适配高密度屏幕手机的px单位。

    .a{
      font-size:12px;
    }
    [data-dpr="2"] .a{
      font-size: 24px;
    }
    [data-dpr="3"] .a{
      font-size: 36px;
    }

    而缩放是动态的,这样,不同设备下的px显示一样的长度。

    之前说过CSS像素和物理像素与缩放、dpr都有关系,这里说明:

    在普通手机上,.a字体设置为12px;

    在dpr是2的手机上,[data-dpr="2"] .a字体为24px,又因为页面缩放50%,字体为还是12px

    总结

    坦白说,我不觉得第一种方案能就做『适配』方案,因为太笨了,只能做一些列表等简单排列的样式

      

  • 相关阅读:
    Promise关键知识
    CSS实现简易的轮播图
    绝对定位和相对定位的一些特性
    行内元素及其浮动
    webpack实践总结
    less语法详解
    js模拟事件
    jquery各种事件绑定的区别
    前端路由实现的关键知识点
    js鼠标事件相关知识
  • 原文地址:https://www.cnblogs.com/JinQingsong/p/6613848.html
Copyright © 2011-2022 走看看