zoukankan      html  css  js  c++  java
  • h5 移动端适配方案思考

    基础概念

    CSS像素(CSS pixels)

    这个是浏览器使用的抽象单位,用来精确度量网页上的内容。平时经常写的100px;height:100px;都是与设备无关的。

    设备独立像素(device independent pixels),也可以称为设备无关的逻辑像素

    meta里面设置width=device-width,这个device-width就是设备独立像素

    在chrome里 看到的ip6为375667,ip4为320480等等都是设备独立像素,它们在数值上与css数值是相等的

    设备像素(device pixels ),也可以称为物理像素

    是显示屏的最小物理单位,每一像素都包含自己的颜色、亮度。像素是没有大小的、是一个抽象概念、是一个相对单位。 关于像素有一个常见的错误理解:认为像素是一个宽高相等的小方块,并且的像素都是“那么大”,但是不知道这个宽高的具体数字。

    分辨率

    泛指量测或显示系统对细节的分辨能力。以ip6手机屏幕为例,分辨率为750×1334,这是指屏幕纵向能显示1920个像素,横向能显示1080个像素

    设备像素比,也成dpr

    设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:
    设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

    适配方案1-固定viewport

    好处:为了宽屏显示更多内容

    日常的 h5 项目使用 viewport 的 initail-scale 为 1,宽度设置配合百分比布局,1px 问题使用 transform 方案会最方便。由于每种设备的设备独立像素不同,最终效果也不同,最后的视觉效果如下:

    问题:如果设计稿中给的是某边框线是 1px,那么按照上述规则,就得设置这个边框为 0.5px,但是部分机型不会支持小数点的 px 尺寸。

    为了得到极细致的真实 1px 单位的边框,衍生出了很多的解决办法,使用的比较多的有两种解决方案。其一为 transform 缩放,其二为动态 viewport。

    transfrom 方案,可以搭配伪元素来使用,如果只是为了得到底边的话,那么设置为高度 1px,然后缩放 y 轴为 0.5。

    .scale {
        position: relative;
    }
    .scale:after {
        content: "";
        position: absolute;
        bottom: 0px;
        left: 0px;
        right: 0px;
        border-bottom: 1px solid #ddd;
        -webkit-transform: scaleY(.5);
                transform: scaleY(.5);
        -webkit-transform-origin :0 0;
                transform-origin :0 0; 
    }
    

    如果需要设置四边的话,则这么设置

    .scale:after{
        content: "";
        pointer-events: none; /* 防止点击触发 */
        box-sizing: border-box;
        position: absolute;
         200%;
        height: 200%;
        left: 0;
        top: 0;
        border-radius: 8px;
        border:1px solid #999;
        -webkit-transform: scale(.5);
                transform: scale(.5);
        -webkit-transform-origin: 0 0;
                transform-origin: 0 0;
    }
    

    适配方案2-动态 viewport 和 REM 适配

    如果是电商的活动页这种对视觉效果比较严谨的,则使用rem和动态viewport方案,最终的视觉效果如下:

    源码如下面,基础思想就是设置根节点元素上得font-size,使之为十六分之一屏幕宽度(类似栅格系统,淘宝为1/10分屏宽,贝贝1/16屏宽)。在设置viewport为1/drp的值就可以了。

    ;(function(win) {
        var h;
        var dpr = win.navigator.appVersion.match(/iphone/gi)?win.devicePixelRatio:1;
        var scale = 1 / dpr;
        var docEl = document.documentElement;
        var metaEl = document.createElement('meta');
        function setUnitA(){
            win.rem = docEl.getBoundingClientRect().width / 16;
            docEl.style.fontSize = win.rem + 'px';
        }
        win.dpr = dpr;
        win.addEventListener('resize', function() {
            clearTimeout(h);
            h = setTimeout(setUnitA, 300);
        }, false);
        win.addEventListener('pageshow', function(e) {
            if (e.persisted) {
                clearTimeout(h);
                h = setTimeout(setUnitA, 300);
            }
        }, false);
        docEl.setAttribute('data-dpr', dpr);
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            var wrap = document.createElement('div');
            wrap.appendChild(metaEl);
            document.write(wrap.innerHTML);
        }
        setUnitA();
    })(window);
    

    iPhone6计算出的根节点元素的font-size为__750px/16=46.876px__,那么跟着设计稿的尺寸,css单位应该这么写:css写的尺寸(单位为rem) = 设计稿里的元素尺寸 / 46.875。这种方案,页面上使用了rem单位的元素在不同倍率手机下css尺寸都不同,例如在iphone5里,css尺寸就是__设计稿元素尺寸 / 46.875 * 40

    然而事情还没有完,如果设计师希望能让大屏的情况显示更多的字,而非把字给这样放大了,那么字体则不能使用rem为单位。看下面的一段代码

    .px2px(@name, @px){
        @{name}: round(@px / 2) * 1px;
        [data-dpr="2"] & {
            @{name}: @px * 1px;
        }
        // for mx3
        [data-dpr="2.5"] & {
            @{name}: round(@px * 2.5 / 2) * 1px;
        }
        // for 小米note
        [data-dpr="2.75"] & {
            @{name}: round(@px * 2.75 / 2) * 1px;
        }
        [data-dpr="3"] & {
            @{name}: round(@px / 2 * 3) * 1px
        }
        // for 三星note4
        [data-dpr="4"] & {
            @{name}: @px * 2px;
        }
    }
    .fontSize(@px) {
        .px2px(font-size, @px);
    }
    

    用法为.fontSize(设计稿里此元素的字体大小) ;,这样就能得到不同倍率下正确的字体大小,不过此法仍然有一个问题,需要穷举出所有的dpr情况,android机子碎片化非常严重,所以总会有一些奇奇怪怪的机型效果不如意。

  • 相关阅读:
    [模板] 循环数组的最大子段和
    [最短路][几何][牛客] [国庆集训派对1]-L-New Game
    [洛谷] P1866 编号
    1115 Counting Nodes in a BST (30 分)
    1106 Lowest Price in Supply Chain (25 分)
    1094 The Largest Generation (25 分)
    1090 Highest Price in Supply Chain (25 分)
    树的遍历
    1086 Tree Traversals Again (25 分)
    1079 Total Sales of Supply Chain (25 分 树
  • 原文地址:https://www.cnblogs.com/everlose/p/12496710.html
Copyright © 2011-2022 走看看