移动端适配

作者: halowyn | 来源:发表于2021-02-20 15:56 被阅读0次

    一、基础概念

    1. 英寸

    一般用英寸描述屏幕的物理大小,如电脑显示器的17、22,手机显示器的4.8、5.7等使用的单位都是英寸。需要注意,上面的尺寸都是屏幕对角线的长度。

    英寸和厘米的换算:1英寸 = 2.54 厘米

    2. 分辨率

    • 2.1 像素

      像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。(ps上图像放大之后可以看到的像素点)

      lADPDeC2uQ_d2rbMyMzI_200_200.jpg
      WX20190821-104756@2x.png
    • 2.2 屏幕分辨率

      屏幕分辨率指一个屏幕具体由多少个像素点组成,当然分辨率高不代表屏幕就清晰,屏幕的清晰程度还与尺寸有关。

    • 2.3 图像分辨率

      我们通常说的图片分辨率其实是指图片含有的像素数,比如一张图片的分辨率为800 x 400。这表示图片分别在垂直和水平上所具有的像素点数为800和400。
      同一尺寸的图片,分辨率越高,图片越清晰。

    3. 设备独立像素

    上面描述的都是物理像素,是设备上真实的物理单元。随着设备分辨率越来越高,同样大小的图片和文字,使用物理像素现实的话将会越来越小


    16ac3a6576e564d5.png

    乔布斯首次提出了Retina Display(视网膜屏幕)的概念,不管分辨率多高,他们所展示的界面比例都是基本类似的。
    在iPhone4使用


    16ac3a65a53a177e.png
    的视网膜屏幕中,把2x2个像素当1个像素使用,这样让屏幕看起来更精致,但是元素的大小却不会改变

    如果黑色手机使用了视网膜屏幕的技术,那么显示结果应该是下面的情况,比如列表的宽度为300个像素,那么在一条水平线上,白色手机会用300个物理像素去渲染它,而黑色手机实际上会用600个物理像素去渲染它。

    我们必须用一种单位来同时告诉不同分辨率的手机,它们在界面上显示元素的大小是多少,这个单位就是设备独立像素(Device Independent Pixels)简称DIP或DP。上面我们说,列表的宽度为300个像素,实际上我们可以说:列表的宽度为300个设备独立像素。

    16ac3a6609e7303b.png

    打开chrome的开发者工具,我们可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,比如iPhone X显示的尺寸是375x812,实际iPhone X的分辨率会比这高很多,这里显示的就是设备独立像素。

    • 3.1 设备像素比
      设备像素比device pixel ratio简称dpr,即物理像素和设备独立像素的比值。

    4. 视口

    视口(viewport)代表当前可见的计算机图形区域。在Web浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的UI, 菜单栏等——即指你正在浏览的文档的那一部分。
    一般我们所说的视口共包括三种:布局视口、视觉视口和理想视口,它们在屏幕适配中起着非常重要的作用。

    • 4.1 布局视口


      16ac3a666e96ff01.png

    布局视口(layout viewport):当我们以百分比来指定一个元素的大小时,它的计算值是由这个元素的包含块计算而来的。当这个元素是最顶级的元素时,它就是基于布局视口来计算的。

    所以,布局视口是网页布局的基准窗口,在PC浏览器上,布局视口就等于当前浏览器的窗口大小(不包括borders 、margins、滚动条)。

    在移动端,布局视口被赋予一个默认值,大部分为980px,这保证PC的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。

    我们可以通过调用document.documentElement.clientWidth / clientHeight来获取布局视口大小。

    • 4.2 视觉视口


      16ac3a66924ef751.png

    视觉视口(visual viewport):用户通过屏幕真实看到的区域。

    视觉视口默认等于当前浏览器的窗口大小(包括滚动条宽度)。

    当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。

    例如:用户将浏览器窗口放大了200%,这时浏览器窗口中的CSS像素会随着视觉视口的放大而放大,这时一个CSS像素会跨越更多的物理像素。

    所以,布局视口会限制你的CSS布局而视觉视口决定用户具体能看到什么。
    
    我们可以通过调用window.innerWidth / innerHeight来获取视觉视口大小。
    
    • 4.3 理想视口


      16ac3a664842c93c.png

      布局视口在移动端展示的效果并不是一个理想的效果,所以理想视口(ideal viewport)就诞生了:网站页面在移动端展示的理想大小。

      如上图,我们在描述设备独立像素时曾使用过这张图,在浏览器调试移动端时页面上给定的像素大小就是理想视口大小,它的单位正是设备独立像素。

      上面在介绍CSS像素时曾经提到页面的缩放系数 = CSS像素 / 设备独立像素,实际上说页面的缩放系数 = 理想视口宽度 / 视觉视口宽度更为准确。

      所以,当页面缩放比例为100%时,CSS像素 = 设备独立像素,理想视口 = 视觉视口。
      我们可以通过调用screen.width / height来获取理想视口大小

    • 4.4 meta viewport

      meta元素表示那些不能由其它HTML元相关元素之一表示的任何元数据信息,它可以告诉浏览器如何解析页面。

      我们可以借助<meta>元素的viewport来帮助我们设置视口、缩放等,从而让移动端得到更好的展示效果。

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

    二、移动端适配方案

    1. flexible方案

    flexible方案是阿里早期开源的一个移动端适配解决方案,引用flexible后,我们在页面上统一使用rem来布局。
    它的核心代码非常简单:

    // set 1rem = viewWidth / 10
    function setRemUnit () {
        var rem = docEl.clientWidth / 10
        docEl.style.fontSize = rem + 'px'
    }
    setRemUnit();
    
    

    rem 是相对于html节点的font-size来做计算的。

    我们通过设置document.documentElement.style.fontSize就可以统一整个页面的布局标准。

    上面的代码中,将html节点的font-size设置为页面clientWidth(布局视口)的1/10,即1rem就等于页面布局视口的1/10,这就意味着我们后面使用的rem都是按照页面比例来计算的。

    这时,我们只需要将UI出的图转换为rem即可。

    以iPhone6为例:布局视口为375px,则1rem = 37.5px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 37.5 = 2rem。

    当然,每个布局都要计算非常繁琐,我们可以借助PostCSS的px2rem插件来帮助我们完成这个过程。

    下面的代码可以保证在页面大小变化时,布局可以自适应,当触发了window的resize和pageShow事件之后自动调整html的fontSize大小。

    // reset rem unit on page resize
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow', function (e) {
        if (e.persisted) {
          setRemUnit()
        }
    })
    
    

    由于viewport单位得到众多浏览器的兼容,上面这种方案现在已经被官方弃用:

    lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。

    2. vw、vh方案

    vh、vw方案即将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 等分为 100 份。

    • vw(Viewport's width):1vw等于视觉视口的1%
    • vh(Viewport's height) :1vh 为视觉视口高度的1%
    • vmin : vw 和 vh 中的较小值
    • vmax : 选取 vw 和 vh 中的较大值


      16ac3a66a99430fc.png

    如果视觉视口为375px,那么1vw = 3.75px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 3.75 = 20vw

    这里的比例关系我们也不用自己换算,我们可以使用PostCSS的 postcss-px-to-viewport 插件帮我们完成这个过程。写代码时,我们只需要根据UI给的设计图写px单位即可。

    当然,没有一种方案是十全十美的,vw同样有一定的缺陷:

    • px转换成vw不一定能完全整除,因此有一定的像素差。
    • 比如当容器使用vw,margin采用px时,很容易造成整体宽度超过100vw,从而影响布局效果。当然我们也是可以避免的,例如使用padding代替margin,结合calc()函数使用等等...

    以上内容参考:https://juejin.im/post/5cddf289f265da038f77696c

    vue-cli 3.0+vw、vh实践

    • 创建项目

      vue create demo

    • 引入postcss-px-to-viewport

      npm install postcss-loader postcss-px-to-viewport --save-dev

    将下面代码放在package.json里,然后重启服务即可

    "postcss": {
        "plugins": {
          "autoprefixer": {},
          "postcss-px-to-viewport": {
            "viewportWidth": 750,
            "viewportHeight": 1334,
            "unitPrecision": 5,
            "viewportUnit": "vw",
            "selectorBlackList": [
              ".ignore"
            ],
            "minPixelValue": 1,
            "mediaQuery": false
          }
        }
    }
    

    相关文章

      网友评论

        本文标题:移动端适配

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