移动web适配方案

PC页面的人聊的最多的就是兼容,这是因为浏览器之间的差异引起的。而移动端是基本没有兼容的问题的,全是CSS3。可是适配的问题随之而来。

手机适配,目前有四种方法:

  • 固定高度,宽度自适应
  • 固定宽度,viewport缩放
  • 利用 rem 布局
  • 利用 vw 布局

这四种方法的核心都是视口的确定


1.固定高度,宽度自适应

目前拉勾网使用的就是这种方式,只适合简单的web app,单位使用px

  • (1)以较小宽度(如 320px)的视觉稿作为参照进行布局
  • (2)固定屏幕为理想视口宽度

  • (3)垂直方向使用定值
  • (4)水平方向混合使用定值和百分比或者利用弹性布局(Felx)

最终达到“当手机屏幕变化时,横向拉伸或者填充空白的效果

移动web适配方案_第1张图片

这是一种典型的弹性布局:关键元素高宽位置都不变,只有容器元素在做伸缩变换。哪个宽度需要调整的时候使用响应式布局调调就行。对于这类app,记住一个开发原则就好:文字流式,控件弹性,图片等比缩放

移动web适配方案_第2张图片

Flex 布局语法教程


2.固定宽度,viewport缩放

设计图、布局视口、视觉视口使用一个宽度,浏览器帮我们完成缩放,单位使用px即可。这种方法也很少见,了解即可

网易金币商城在使用这种方法

移动web适配方案_第3张图片

原理
这种方法需要根据屏幕宽度来动态生成viewport,生成的 viewport 基本是这样:


640 是我们根据设计图定下的,0.5625 是根据屏幕宽度动态生成的。

生成的viewport告诉浏览器网页的布局视口使用 640px,然后把页面缩放成56%,这是绝对的等比例缩放。图片、文字等等所有元素都被缩放在手机屏幕中。


移动web适配方案_第4张图片

通过 js 动态设定 initial-scale

var fixScreen = function() {
    var metaEl = doc.querySelector('meta[name="viewport"]'),
        metaCtt = metaEl ? metaEl.content : '',
        matchScale = metaCtt.match(/initial\-scale=([\d\.]+)/),
        matchWidth = metaCtt.match(/width=([^,\s]+)/);

    if ( metaEl && !matchScale && ( matchWidth && matchWidth[1] != 'device-width') ) {
        var width = parseInt(matchWidth[1]),
            iw = win.innerWidth || width,
            ow = win.outerWidth || iw,
            sw = win.screen.width || iw,
            saw = win.screen.availWidth || iw,
            ih = win.innerHeight || width,
            oh = win.outerHeight || ih,
            ish = win.screen.height || ih,
            sah = win.screen.availHeight || ih,
            w = Math.min(iw,ow,sw,saw,ih,oh,ish,sah),
            scale = w / width;

        if ( scale < 1) {
            metaEl.content += ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale;
        }
    }
}

3.使用rem布局

依照某特定宽度设定 rem 值(即 html 的 font-size),页面任何需要弹性适配的元素,尺寸均换算为 rem 进行布局;当页面渲染时,根据页面有效宽度进行计算,调整 rem 的大小,动态缩放以达到适配的效果

最典型的就是网易新闻和手机淘宝Flexible方案。

3.1 网易新闻方案

移动web适配方案_第5张图片
  • (1) 网易新闻的设计稿应该是基于iphone6/7/8,所以它的设计稿竖直放时的横向分辨率为750px,为了计算方便,取1rem=100px为参照,那么html元素的宽度就可以设置为width: 7.5rem,于是html的font-size=deviceWidth / 7.5

  • (2) 媒体查询改变根元素的字体大小
    媒体查询参考

/**
 * view-port list:
320x480
320x568
320x570
360x592
360x598
360x604
360x640
360x720
375x667
375x812
393x699
412x732
414x736
480x854
540x960
640x360
720x1184
720x1280
800x600
1024x768
1080x1812
1080x1920
 */
@media screen and (max-width: 320px) {
  html {
    font-size: 42.667px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 321px) and (max-width: 360px) {
  html {
    font-size: 48px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 361px) and (max-width: 375px) {
  html {
    font-size: 50px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 376px) and (max-width: 393px) {
  html {
    font-size: 52.4px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 394px) and (max-width: 412px) {
  html {
    font-size: 54.93px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 413px) and (max-width: 414px) {
  html {
    font-size: 55.2px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 415px) and (max-width: 480px) {
  html {
    font-size: 64px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 481px) and (max-width: 540px) {
  html {
    font-size: 72px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 541px) and (max-width: 640px) {
  html {
    font-size: 85.33px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 641px) and (max-width: 720px) {
  html {
    font-size: 96px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 721px) and (max-width: 768px) {
  html {
    font-size: 102.4px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}
@media screen and (min-width: 769px) {
  html {
    font-size: 102.4px;
    font-size: -webkit-calc(13.33333333vw);
    font-size: calc(13.33333333vw);
  }
}

缺点:媒体查询不能完全枚举,只能大体覆盖。如果想要精确覆盖要通过js实现

document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5+ 'px';
  • (3) 视口设置理想视口

  • (4) 布局时,设计图标注的尺寸除以100得到css中的尺寸(单位用rem)
3.2 使用Flexible实现手淘H5页面的终端适配

lib-flexible

Flexible要点:

  • (1) 第一步是根据设备像素比动态设置viewport的scale
if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

var metaEl = doc.createElement('meta');
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
    document.documentElement.firstElementChild.appendChild(metaEl);
} else {
    var wrap = doc.createElement('div');
    wrap.appendChild(metaEl);
    documen.write(wrap.innerHTML);
}

适配结果:

 
 
 

  

  • (2)第二步,设置html元素的font-size:font-size = deviceWidth / 10,即1rem=deviceWidth / 10(px)
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
  • (3) 布局的时候,各元素的css尺寸(rem)=设计稿标注尺寸(px)/设计稿横向分辨率/10

font-size可能需要额外的媒介查询,并且font-size不使用rem。详细看使用Flexible实现手淘H5页面的终端适配

注意!!!

最新版(amfe-lexible)已经不再修改 viewport ,而是统一使用理想视口。

3.3网易与老版手机淘宝的做法不同点
  • (1) 淘宝需要动态设置viewport的scale,网易直接设置为理想视口。Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr为1。也就是说在安卓下,淘宝的视口设置和网易新闻是一样的,
  • (2) 网易的做法,rem值很好计算,淘宝的做法肯定得用计算器或者sass和less这样的css处理器

4.使用vw进行布局

vw:是Viewport's width的简写,1vw等于window.innerWidth1%

Flexible方案是通过JavaScript来模拟vw的特性。到今天为止,vw已经得到了众多浏览器的支持,也就是说,我们完全可以考虑将vw单位运用于我们的适配布局中,当然你也可以继续使用rem


参考

MobileWeb 适配总结


更多阅读

移动端Web页面适配方案
使用Flexible实现手淘H5页面的终端适配
了解真实的『REM』手机屏幕适配

你可能感兴趣的:(移动web适配方案)