Loading

移动端适配

Shibiao Zhang

This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.

移动端适配

几个概念

  • Viewport
  • scale 缩放
  • dpr
  • css

单位

  • em
  • rem
  • %
  • css
  • vw/vh

vw/vh innerwidth/height

rem

 

zoom缩放

(function(){
    var _w,
        _zoom,
        _hd,
        _orientationChange,
        _doc = document,
        _style = _doc.getElementById("_zoom");
    _style || (
        _hd = _doc.getElementsByTagName("head")[0],
        _style=_doc.createElement("style"),
        _hd.appendChild(_style)
    );
    _orientationChange = function(){
       _w    = _doc.documentElement.clientWidth || _doc.body.clientWidth;
       _zoom = _w / 640;
       _style.innerHTML = ".zoom {zoom:" + _zoom + ";-webkit-text-size-adjust:auto!important;}";
    };
    _style.setAttribute("zoom",_zoom);
    _orientationChange();
    window.addEventListener("resize",_orientationChange,false);
})();

完美视口

<meta name="viewport" 
content="initial-scale=1.0,
width=device-width,
user-scalable=0,maximum-scale=1.0"/>

定宽布局

固定某种机型,两边留白

宽度自适应

宽度百分比,px定高

定宽viewport


<meta name="viewport" content="width=320,maximum-scale=1.3,user-scalable=no">

假定设计稿都是基于320的,我们可以将width设为320,然后在这个基础上进行一定比例的缩放,这个比例是当前设备宽度/320计算出来动态修改的。利用这一方式可以非常快捷实现适配的目的,简单粗暴、非常高效

(legend采用这种方式,编辑器基本都是这个思路,方便定位)

网易前端解决方案

对于Android设备,由于只设置宽度它并不会主动进行缩放


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

<meta content="target-densitydpi=device-dpi,width=640,initial-scale=0.5625,maximum-scale=0.5625" name="viewport">

网易demo,ios

优点

  • 实现简单
  • 按照固定ue尺寸切图

缺点

定宽有个坑
就是如果你的页面要嵌入到App中时,App是以webview的形式渲染页面的。
webview实际上也是webkit内核,而最新的webkit内核对定宽支持不是很好,
他默认是以device-width来渲染的。这样一来你的页面就被放大了,
窗口还有滚动条,解决办法是让app开发帮忙设置两个属性:
WebSettings webSettings = view.getSettings(); webSettings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
可是App开发说这样影响性能。所以我觉得用device-width是最靠谱的

淘宝

淘宝

viewport+scale+dpr+rem

scale=1/dpr

页面10等分

1rem=10vw

viewport+scale+dpr+rem

var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');

dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * 2 / 10;
scale = 1 / dpr;


// 设置viewport,进行缩放,达到高清效果
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');

// 设置data-dpr属性,留作的css hack之用
docEl.setAttribute('data-dpr', dpr);

// 动态写入样式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';

组合式:why?

根据设备的dpr动态设置页面的viewport以达到对页面进行一定缩放的目的,来使得页面能按照物理像素来进行渲染,提高页面的清晰度,同时能愉快地写出1px宽的元素。网易定为640为适配dpr=2,ip4、5,legend定位400很奇怪

why?

用REM做单位与百分比做单位有什么优势?

主要优势在于能更好的控制元素大小。(一般百分比应用在布局层,一般常见设置为50%,33.3%,25%之类的整数居多,难以运用在复杂的页面小部件内)。
但是相比百分比布局,需要借助JS或media query实现,略有一点瑕疵

纯rem缩放

initial-sacle=1写死viewport

根据device-width计算rem的font-size的转换

假定固定的ue图,375/750

less=>css的转换,切图按照固定的ue图

(function (doc, win) {
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if (!clientWidth) return;
            // 可根据实际情况更改,来源代码是
            //docEl.style.fontSize = 100 * (clientWidth / 320) + 'px';
           // 方便计算采用*2/100 主要是避免小数点的情况
            docEl.style.fontSize = 2*clientWidth/100 + 'px';
        };

    // Abort if browser does not support addEventListener
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
@remPerPix: 1/75rem;
// per px => rem

// if ue layout is 750px
//.main 375px
.main {
    width:150*@remPerPix;
}


output css=>
.main {
  width: 2rem;
}

rem 有什么不妥

段落文字的字号大小设置不适合使用rem来设置,还是应该使用px

计算偏差(“挤下来”等情况)

文字在高分辨率手机上显示过小的问题(media query)

flex布局

flex的兼容性

优于百分比的布局

高度?

vw vh

兼容性

summary

只做屏幕适配,viewport sacle1. +百分比+部分rem的实现

组合式适配解决1px ,充分利用屏幕分辨率

在贴吧现有基础库的基础上不适合用viewport+scale

可以部分用rem来实现复杂部件的适配,约定固定的ue图

倾向于组合式,淘宝的解决方案

lib-flexible为vw,vh做了兼容

不同dpr采用不同尺寸的图片

未来

QA

flex

em

width:10em;em基数是应用于当前元素的font-size

特例:

  .parent {
            width: 300px;
            height: 300px;
            font-size: 20px;
            border: solid 1px red;
      }

   .child {
    border: solid 1px green;
    font-size: 10px;
    width: 10em;
    /*400px*/
    height: 10em;
   }
output => 

width: 120px;
font-size:10px;


inherited => font-size:12px;


2.

.child {
    border: solid 1px green;
    font-size: 2em;
    width: 10em;
    height: 10em;
   }

output=> font-size:40px;width:400px;

rem

优缺点

  • 暴力简单
  • 不适用于复杂页面,整体缩放容易导致问题
  •  uc支持性不好
  • 设置缩放后,当滚动页面的时候,在活动对应元素的offset() 里面的top值会变,这样容易导致混乱
  • 所以废弃。。。
Made with Slides.com