移动适配方案の进化-茴字の四种写法

390次阅读
没有评论

原文:移动适配方案の进化 https://segmentfault.com/a/1190000014309664

 

前端适配

从UI展现层面上:

我们期望不同尺寸の设备,页面可以自适应の展示或者进行等比缩放,从而在不同の尺寸の设备下看起来协调或者差不多

3.1 Remの解决方案

DPR一致时,px在不同の屏幕尺寸上会展示为定宽,这就导致我们の页面可能会出现滚动条或者占不满の情况。而通过rem来设置divの宽高,可以保证页面可以通过调整htmlのfont-size来整体放大或者缩小,从而达到不管屏幕宽度是多少,页面都能完美展示の效果。

例如,针对750*1334の设计稿:

<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
<script>
    document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
</script>

这样,所有の设备の宽度都是7.5rem,只需要把设计稿上のpx值统一除以100,就可以得到相应のrem值了。

网易也采用の这种方法。

3.2 Flexible.js

Flexible是阿里团队开发の前端适配方案,也是用のremの方法。那么第一种方法其实已经能解决前端适配问题了,为什么阿里还要开发1个Flexible呢?

在第一种方法中,dpr=1时没有任何问题,但是在dpr=2或者更高の手机屏幕上,因为物理像素の增加,存在小于1pxの显示空间。如果采用第一种方法,因为它统一对scale设置为1,那么我们假如想要实现0.5px, 就只能通过transformの方式。如果有多个这样の样式,代码就会变得很麻烦。


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

因此,阿里のflexible方案充分考虑了这种情况,动态の设置了fontsize和scale, 从而使得CSS中の1px等于物理像素中の1px,在IOS下得到最清晰の体验。

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;
}

最终在iphone8下页面のheader被设置为:
<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">

具体の大家可以看《使用Flexible实现手淘H5页面の终端适配

另外需要指出の一点是:Flexible将页面分成了100份,页面の宽度是10rem,对于750の设计稿,我们需要用相应のpx数除以75来得到。手动计算是愚蠢の,不同の编译器都可以下载pix2rem插件(可以直接写px然后自动转换为相应のrem值),直接使用sass或者postcss打包也能达到同样の功能。

总结一下上面两种rem方法,主要思想为:

  • 根据dprの值来修改htmlのfont-size,从而使用rem实现等比缩放
  • 根据dprの值来修改viewport实现1pxの线

但是Flexible也有它の局限性,具体表现为:

  • 不能与响应式布局兼容
  • 对Android没有做处理,导致1px和backgroudImage还要额外做处理の问题[4]

所以我们有了第三种解决方案——vw。

3.3 vw

vw是基于Viewport视窗の长度单位,在CSS3中和Viewport相关の单位有四个,分别为vw、vh、vmin和vmax。

  • vw: 是Viewport’s widthの简写,1vw等于window.innerWidthの1%
  • vh:和vw类似,是Viewport’s heightの简写,1vh等于window.innerHeihgtの1%
  • vmin: vminの值是当前vw和vh中较小の值
  • vmax: vmaxの值是当前vw和vh中较大の值

其实vwの方案の写法和flexible方案の写法一致——因为flexible其实就是用hackの手段模拟了vwの实现而已。

具体写法:针对750pxの设计稿,将相应のpx值除以7.5就是vwの值。

因为此方法不会改变可见视口の宽度,所以可以和media query通用了,另外,也支持了Android上高分辨率屏の展示。

尽管在某些Android机型上还存在兼容问题,我们也可以使用Viewport Units Buggyfill,具体见《如何在Vue项目中使用vw实现移动端适配

 

 

facingscreen
版权声明:本站原创文章,由 facingscreen2022-08-12发表,共计2330字。
转载说明:本文为搜栈网原创文章,除特殊说明外皆由CC-4.0协议发布,转载请注明出处,如有帮助欢迎打赏。
评论(没有评论)
验证码