当前位置 : 主页 > 手机开发 > 无线 >

关于移动端适配

来源:互联网 收集:自由互联 发布时间:2021-06-10
主要要解决的适配问题有 1. 元素自适应问题 2. 文字大小和边框问题 3. 高清图问题 4. 1像素问题 5. 横竖屏显示问题 我们css中的1px,通常叫做css像素(虚拟像素),物理像素 与虚拟像素

主要要解决的适配问题有

1.  元素自适应问题

2. 文字大小和边框问题

3. 高清图问题

4. 1像素问题

5. 横竖屏显示问题

我们css中的1px,通常叫做css像素(虚拟像素),物理像素 与虚拟像素的比就称为设备像素比(dpr)

现在现代浏览器都支持 window.devicePixelRatio

 

一.  元素自适应问题

通过rem解决,rem不仅可以设置字体大小,还可以设置块的宽高,相比与@media,可以支持中间屏幕,且公用一套样式,减少工作量

二.  文字大小

对于文字大小,如果没有要求严格还原设计稿,就不要使用rem自动调整大小。原因是:

① 在大屏幕下希望看到更多的文字(使用rem,文字在所有屏幕上显示的个数一样,只是大小不一样)

② 中文点阵最好在12px, 14px, 16px,使用rem无法避免13px这些

1 2 3 4 5 6 7 8 9 div {      font-size: 12px;  // 默认写上dpr为1的fontSize } [data-dpr= "2" ] div {      font-size: 24px; } [data-dpr= "3" ] div {      font-size: 36px; }

对于阿里的lib-flexible,是通过判断dpr的值动态给body标签添加font-size属性;原理相似;后面会贴出我修改的源码

三. 高清图问题

1. 使用 srcset标签(WebKit最新特性srcset简介)

<img src="http://img.558idc.com/uploadfile/allimg/210610/235P02564-0.jpg" srcset="http://img01.taobaocdn.com/imgextra/i1/803091114/TB2XhAPaVXXXXXmXXXXXXXXXXXX_!!803091114.jpg 2x, http://gtms04.alicdn.com/tps/i4/TB1wDjWGXXXXXbtXVXX6Cwu2XXX-398-510.jpg_q75.jpg 3x">

2、使用js自带的 Image 异步加载图片

复制代码
<img id="img" data-src1x="[email protected]" data-src2x="[email protected]" data-src3x="[email protected]"/>

var dpr = window.devicePixelRatio;
if(dpr > 3){
    dpr = 3;
};

var imgSrc = $(‘#img‘).data(‘src‘+dpr+‘x‘);
var img = new Image();
img.src = imgSrc;
img.onload = function(imgObj){
    $(‘#img‘).remove().prepend(imgObj);//替换img对象
};
复制代码

3. 背景图片高清解决方法(对于dpr=2,1个css像素对应4个物理像素)

对于dpr=1,物理像素和css相同,图片高清。但对于dpr=2,导致每个像素点实际上有4倍的普通像素点,反过来说,一个CSS像素点实际分成了四个,这样就造成了颜色只能近似选取,于是,我们看上去就变得模糊了。所以使用2x的图片就刚刚好。。

但对于dpr=1,如果使用2x的图片,由于一个css像素对应4个物理像素可以选择,这是就会缩小像素采样(Downsampling)

①使用media来处理

复制代码
/* 普通显示屏(设备像素比例小于等于1)使用1倍的图 */
.css{
    background-image: url(img_1x.png);
}

/* 高清显示屏(设备像素比例大于等于2)使用2倍图  */
@media only screen and (-webkit-min-device-pixel-ratio:2){
    .css{
        background-image: url(img_2x.png);
    }
}

/* 高清显示屏(设备像素比例大于等于3)使用3倍图  */
@media only screen and (-webkit-min-device-pixel-ratio:3){
    .css{
        background-image: url(img_3x.png);
    }
}
复制代码

②使用image-set来处理

复制代码
.css {
    background-image: url(1x.png); /*不支持image-set的情况下显示*/
    background: -webkit-image-set(
            url(1x.png) 1x,/* 支持image-set的浏览器的[普通屏幕]下 */
            url(2x.png) 2x,/* 支持image-set的浏览器的[2倍Retina屏幕] */
            url(3x.png) 3x/* 支持image-set的浏览器的[3倍Retina屏幕] */
    );
}
复制代码

四. 1px问题(retina,即视网膜屏幕)

 什么是 1像素问题 ? 我们说的1像素,就是指1CSS像素。问题就是设计师实际了一条线,本来是1像素,但是在有些设备上,用了横竖都是3的物理像素(即:3x3=9像素)来显示这1像素(即:dpr=3),导致在这些设备上,这条线看上去非常粗!

1. 使用css3的 scaleY(0.5) 来解决

不过这种方法通常是通过伪类来实现的,所以一个div只能实现两条线,有四周都有的话要创建两个DIV。且只能实现直线问题

复制代码
.div:before {
  content: ‘‘;
  position: absolute;
  left: 0;
  top: 0;
  bottom: auto;
  right: auto;
  height: 1px;
  width: 100%;
  background-color: #c8c7cc;
  display: block;
  z-index: 15;
  -webkit-transform-origin: 50% 0%;
          transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  .div:before {
    -webkit-transform: scaleY(0.5);
            transform: scaleY(0.5);
  }
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
  .div:before {
    -webkit-transform: scaleY(0.33);
            transform: scaleY(0.33);
  }
}
复制代码

 对于移动端适配,我现在用下列代码

复制代码
(function flexible (window, document) {
    var docEl = document.documentElement;
    console.log(docEl);
    var dpr = window.devicePixelRatio || 1;

    if( 2 < dpr && dpr < 3){
        dpr = 2;
    }else if( dpr > 3 ) {
        dpr = 3;
    }
    docEl.setAttribute("data-dpr", dpr);
    // adjust body font size
    function setBodyFontSize () {
    if (document.body) {
          document.body.style.fontSize = (12 * dpr) + ‘px‘;
    }
    else {
          document.addEventListener(‘DOMContentLoaded‘, setBodyFontSize);
    }
    }
    setBodyFontSize();

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

    setRemUnit();

    // reset rem unit on page resize
    window.addEventListener(‘resize‘, setRemUnit);
    window.addEventListener(‘pageshow‘, function (e) {
        if (e.persisted) {
              setRemUnit();
        }
    })
    console.log(dpr);
    // detect 0.5px supports
    if (dpr >= 2) {
        var fakeBody = document.createElement(‘body‘);
        var testElement = document.createElement(‘div‘);
        testElement.style.border = ‘.5px solid transparent‘;
        fakeBody.appendChild(testElement)
        docEl.appendChild(fakeBody);
        if (testElement.offsetHeight === 1) {
              docEl.classList.add(‘hairlines‘);//ios7以下,android等其他系统里,0.5px会被显示为0px,是IOS8+,是的话则加上hairlines的类名
        }
        docEl.removeChild(fakeBody);

      }
}(window, document))
复制代码

对于解决1px问题,有时直接通过js在meta标签里改页面缩放就能完美解决。。但是本人还是用不惯。

这种解决方案的原理就是:将页面整体所缩小1/2,又将html根字体扩大了2倍。所以,对于页面上使用rem的元素,等于没有变化,但是使用px的元素,由于页面缩小了1/2,所有元素尺寸就相当于缩小了1/2。对于上面的例子来说,1px就相当于0.5px了。

https://github.com/amfe/lib-flexible/tree/master(lib-flexible的第一版本)

网友评论