移动端配置

物理像素

iphone 6 的宽度有750个物理像素

逻辑像素

也叫设备的独立像素,css像素也是逻辑像素的一种

逻辑像素比(dpr)

物理像素➗逻辑像素,iphone6 的dpr=2

常见问题

  • 图片模糊
  • 1px问题

1.图片模糊

一个图片大小200px * 200px(逻辑像素) 在dpr为1的屏幕下显示正常,在dpr为2的情况下那么在200px * 200px(逻辑像素)下物理像素是400px * 400px(物理像素)

本来一个物理像素点就好了现在变成了(2*2)个,那么问题来了,其他的物理像素点会去找相近的颜色去填充,所以就变的模糊了

2.1px问题

这个问题很有意思,真的给我上了一课以后看文章,真的要多看一些在做出选择为什么呢?

网上很多人的说法:因为dpr>1所以导致边框线变粗,我就很奇怪1px变粗,那为什么没有2px问题,3px问题,4px问题...,为什么2px,3px,4px不会变粗,然道他们的dpr不是>1吗?明显他们就说错了,但是哇,就很夸张很多人写的都是因为dpr的原因?

我认为:其实就是在一个750px的设计图上的边框为1px那么按照比例在iphone6->375px逻辑像素下<-下显示的的边框按比例是0.5px其实就是这样而已,其实有些公司会把这个1px在移动端变成.5px(阿里巴巴,JD)都是变了的,但是也有没有变的,为什么呢?应为其实边框本来就是不支持百分比的所以其实我认为按照css规范其实设计图1px那么不管在什么屏幕下应该都是1px,而不是去缩放边框(阅文的官网,google)我看的就是1px还是1px,其实这个和UI说的算的咯

国内知名互联网企业移动端H5尺寸适配方案

1.很多年前淘宝的lib-flexible移动端配置方案

原理:通过dpr,去动态生成缩放视口,从而逻辑像素等于物理像素,那么在动态生成html下的字体大小就可以控制rem了,比如在750的设计稿下,一个div为75px,那么我们可以1rem,

缩放视图

var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

根据不同移动设备动态计算font-size

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

但是这个已经被淘汰了,由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,

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

作用

  1. 以ip6为例子,在逻辑像素比为2的情况下可以看到750px,但是通过设置width=device-width,让视图可视宽度,变成设备的逻辑像素为350px

注意:

  1.  initial-scale=1.0 和 width=device-width的效果是一样的一起写的作用是处理不同浏览器的兼容问题
  2. 设置完成后,那么我们就要防止就是图片大小过低导致不清晰的问题了

JD

    /* JD的移动端刷屏 */
    html {
      font-size: 20px;
      font-size: 5.33333vw
        /* 3.75px * 5.33333 ~ 20px */
    }

    @media screen and (max-width:320px) {
      html {
        font-size: 17.06667px
      }
    }

    @media screen and (min-width:540px) {
      html {
        font-size: 28.8px
      }
    }

其实这个就很有意思,不会根据屏幕大小改变一点就去变一点,而是在一个范围,然后再弹性布局

百度

html {
    font-size: 100px
}

@media screen and (max-width: 360px) {
    html {
        font-size:90px;
        line-height: 90px
    }
}

body {
    font-size: 16px;
}

阅文

html {
    font-size: 16px;
}

@media screen and (min-width: 375px) {
    html {
        /* iPhone6的375px尺寸作为16px基准,414px正好18px大小, 600 20px */
        font-size: calc(100% + 2 * (100vw - 375px) / 39);
        font-size: calc(16px + 2 * (100vw - 375px) / 39);
    }
}
@media screen and (min-width: 414px) {
    html {
        /* 414px-1000px每100像素宽字体增加1px(18px-22px) */
        font-size: calc(112.5% + 4 * (100vw - 414px) / 586);
        font-size: calc(18px + 4 * (100vw - 414px) / 586);
    }
}
@media screen and (min-width: 600px) {
    html {
        /* 600px-1000px每100像素宽字体增加1px(20px-24px) */
        font-size: calc(125% + 4 * (100vw - 600px) / 400);
        font-size: calc(20px + 4 * (100vw - 600px) / 400);
    }
}
@media screen and (min-width: 1000px) {
    html {
        /* 1000px往后是每100像素0.5px增加 */
        font-size: calc(137.5% + 6 * (100vw - 1000px) / 1000);
        font-size: calc(22px + 6 * (100vw - 1000px) / 1000);
    }
}

网易

(1)以iphone6作为参照,iphone6的宽度是375px,dpr为2,所以对于上面显示的375px的图,我们需要的图片大小是750px,所以我们拿到的psd设计图的宽度必须是750px。为了方便书写rem,我们希望psd设计图上750px对应的rem是7.5rem。而设计图上面750px在iphone6上面的实际大小是375px,所以我们需要设置iphone6的font-size=375/7.5px=50px。更一般地,由于移动端的font-size的默认值是16px,所以我们更倾向于用一个百分比来设置font-size:font-size=50/16=312.5%。(注意:用px和百分比没有本质上的不同。这里也可以不除以16直接乘50,同百分比后续也是要乘以16px的)

(2)在其它屏幕上进行缩放,为了解决这个问题,我们用js来读取屏幕的宽度,然后利用这个宽度来进行缩放,代码如下:

var initScreen=function(){
    $("html").css("font-size", document.documentElement.clientWidth / 375 * 312.5 + "%");
}

最后,我们需要解决横屏问题和用户手动缩放问题,他们本质上都是改变屏幕宽度的问题,所以我们监听resize事件或者onorientationchange事件,当发生的时候,重新调用initScreen方法。代码如下:

$(window).on('onorientationchange' in window ? 'orientationchange' : 'resize', function () {
    setTimeout(initScreen, 200);
});

注意:上面的代码并不是原生js,要引入zepto库!也可以用原生js实现,不过要考虑兼容性问题,我就不贴出代码了。

注意:我这种适配方案中,1rem的实际大小是50px,而不是100px。所以0.12rem的字体,在设计稿上面是12px,但是在手机上的实际大小是6px

另外,为了增加代码的健壮性,在js加载不成功的时候也能进行适配,建议在css加上媒体查询:

@media screen and (max-width: 320px) {
    html {
        font-size:42.667px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 321px) and (max-width:360px) {
    html {
        font-size:48px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 361px) and (max-width:375px) {
    html {
        font-size:50px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 376px) and (max-width:393px) {
    html {
        font-size:52.4px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 394px) and (max-width:412px) {
    html {
        font-size:54.93px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 413px) and (max-width:414px) {
    html {
        font-size:55.2px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 415px) and (max-width:480px) {
    html {
        font-size:64px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 481px) and (max-width:540px) {
    html {
        font-size:72px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 541px) and (max-width:640px) {
    html {
        font-size:85.33px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 641px) and (max-width:720px) {
    html {
        font-size:96px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 721px) and (max-width:768px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}
@media screen and (min-width: 769px) {
    html {
        font-size:102.4px;
        font-size: 13.33333vw
    }
}

目前淘宝

    解读

1.开始函数先来匿名函数

2.找到HTML文档对象,因为后面要给他定义fontSize的值;

3.找到dpr的值,如果大于等于2,就给这个设备设置0.5px的边框

4.除以3.75的解释:如果设计图为750那么就是除以7.5为什么是7.5 ? 因为我们以100px为1rem那么750的设计图为7.5rem,那么我们要求出不同设备的rem的值就是用n.clientWidth/7.5就是rem的值

5.函数i给html定义fontSize的值

6.最后if()中的条件: 

        6-1:判断 是否存在document.body 再设置html标签的font-size的值

        6-2:设置html标签的font-size的值,

        6-3:设置监听横屏事件,和判断是否是缓存 

        6-4:最后判断drp的值:是否设置.5px的边框

 7.if{}中的代码是判断是否支持.5px,支持添加属性hairlines

    // 解读
    // e = window ; t = document
    // n === document.documentElement 是一个会返回文档对象(document)的根元素的只读属性(如HTML文档的 <html> 元素 
    //  d === window.devicePixelRatio 返回当前显示设备的dpr 
    // 这里 / 3.75 的解释
    // 设计图以iPhone6的分辨率为标准(750x1334)
    // 把上面代码中的3.75改为7.5(如果设计图以375x667为标准则不用改)
    // 前端写CSS时把设计图的单位统一以除以100,然后使用rem单位。
    !function (e, t) {
      var n = t.documentElement // document.documentElement
        , d = e.devicePixelRatio || 1; // dpr
      function i() {
        var e = n.clientWidth / 3.75;
        n.style.fontSize = e + "px"
      }

      // 判断 是否存在document.body 再设置html标签的font-size的值,监听横屏事件,和判断是否是缓存,和判断drp的值
      if (function e() {
        t.body ? t.body.style.fontSize = "16px" : t.addEventListener("DOMContentLoaded", e)
      }(),
        i(),
        e.addEventListener("resize", i), // 当屏幕变成横屏的时候触发事件
        // onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发
        e.addEventListener("pageshow", function (e) {
          // e.persisted : 返回boolead类型 是否是来自缓存数据,如果是那么也会触发i()
          e.persisted && i()
        }),
        // 当 drp 大于等于2的时候
        2 <= d) {
        // 以下代码是再处理.5xp的兼容问题 
        // createElement//创建元素节点
        var o = t.createElement("body")
          , a = t.createElement("div");
        a.style.border = ".5px solid transparent",
          // appendChild//让他成为这个文档现有节点的一个子节点
          o.appendChild(a),
          n.appendChild(o),
          // offsetHeight 元素再垂直方向上的时间 offsetHeight=height+padding+border 
          // 判断是否支持.5px支持,添加属性
          // classList.add 添加属性  
          1 === a.offsetHeight && n.classList.add("hairlines"),
          // removeChild() //方法可从子节点列表中删除某个节点
          n.removeChild(o)
      }
    }(window, document)

解决1px问题

代码来自JD移动端页面

处理情况:分界线

li:after{
  content: "";
  height: 0;
  display: block;
  border-bottom: 1px solid #ddd;
}

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  .li:after{
    -webkit-transform: scaleY(.5);

     // 设置源点的位置
     // transform的缩放是像源点逼近

    -webkit-transform-origin: 50% 100%;
  }

}

处理情况:边框

li:after{
    content: "";
    display: block;
    border: 1px solid #ddd;
    /* 穿透,click点击这个无效 */
    pointer-events: none;
    /* 设置全局大小 */
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  .li:after{
    // 先缩小一半,大小和边框
    -webkit-transform: scale(.5);
    -webkit-transform-origin: 0 0;
    /* 覆盖上面的样式,将大小面积放大一倍 ,这样只有边框缩小*/
    bottom: -100%;
    right: -100%;
  }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值