Open youngwind opened 8 years ago
屏幕尺寸适配一直是移动web开发的大问题,在进行UI组件库的开发的时候,必然绕不过这个问题。不过,我想跳出组件库的范畴,从更广泛的角度谈一谈移动端屏幕尺寸适配。
基于rem的适配方案在数年前就已经兴起,并且一直沿用至今,较为系统的代表是淘宝的flexible 。 关于如何使用这套体系,前人之述备矣。我就不赘述了。 下面重点说一下我的使用体会。
问题:在flexible体系当中引入dpr的概念,但是却又在代码中强制指定所有安卓的dpr都是1。如下代码片段。
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; }
为什么要这么做? 官方的说法是:当时安卓很多机型的dpr都是假的。参考这里
然而,我们从这儿也可以发现:即便设置的dpr与安卓机真实的dpr不同,但是适配方案仍然能正常工作。也就是说,设置的dpr与真实的dpr是否相等其实根本不影响此适配方案 我们还可以从源代码的另一方面来佐证这个结论。
// line 51 scale = 1 / dpr; // line 58 metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); // line 68 var width = docEl.getBoundingClientRect().width; // 这个width是会根据scale按倍数缩放的 var rem = width / 10; docEl.style.fontSize = rem + 'px';
发现没?其实本质上是先通过根元素的fontSize放大dpr倍,然后再通过viewport的scale缩小dpr倍,仅此而已。
既然dpr不影响适配,那么方案中为什么要引入它? 答案:是因为要同时解决“1px边框问题”和“高清图片问题”了,具体的可以参考这篇文章。
flexible改变根元素的fontSize和viewport的scale,相当于js里面的改变了两个全局变量。那么我页面当中的所有其他元素都必须按照这个基准进行,这样我们在嵌入第三方内容的时候就会很不方便。比如:
既然rem有一些问题,那么有替代方案吗?flexbox布局很早就出来了,迟迟不能广泛使用还是因为兼容性的问题。但是天猫已经率先使用了,可以参考如何看待手机天猫首页改用 flex 布局?与手机淘宝首页的 Rem 方案相比有何优缺点? 在回答”flexbox能否提到rem“这个问题之前,我仔细对比天猫的首页和淘宝的首页,会发现一些有趣的东西。 下图分别是iPhone5s和iPhone6p的对比图。(竖着排版对比不方便,建议把图片下载下来切换对比)
我们可以观察到一个现象: 对于天猫而言,6p比5s显示的内容显然要更多。对于淘宝而言,6p与5s显示的内容几乎是一样多。 为什么会这样呢?按理说这两个网站肯定都做到了适配的啊?
问题的答案在于:适配的标准不同。对于淘宝而言,当屏幕变大的时候,适配的效果是”按照比例放大“,元素的宽和高都按倍数增加,所以看到的内容一样多。对于天猫而言,当屏幕变大的时候,适配的效果不是”按照比例放大“,而是高度不变,宽度变化。所以可以看到更多的内容。两个标准都是可以接受的。如果是要做到第一个标准,则需要采取flexible方案,如果要做到第二个标准,则需要采取flexbox方案。
以前我们讨论响应式的标准的时候常常是这样考虑的:”当一个div在小屏幕是这么大的时候,那么在大屏幕下应该是多大呢?“但是,其实这种考虑是片面的。因为真实的需要考虑适配的场景往往不仅仅是div那么简单。比如这个div里面可能是文字,也可能是按钮,也可能是图片等等。我觉得有一个规则非常的好。
文字流式,控件弹性,图片等比缩放。
出处:http://www.ui001.com/article/123.html
举例:看刚才天猫的那个例子,中间那”十大金刚“,当屏幕变大的时候,它们只不过是相互之间的距离变大的,”金刚“入口本身的大小是没有发生改变的,这就是所谓的”控件弹性“。而淘宝则不是。上面的图片已经标注出了这种差异。
说来说去,还是那句话:”生命不息,折腾不止“。关于移动端适配,以后可能有更好的解决方案,但是可以预见的是,依旧会有新的问题冒出来。最近刚刚看了张鑫旭大大写的文章基于vw等viewport视区相对单位的响应式排版和布局,也许会成为未来流行的适配方案。
我有点疑惑,为什么weui 组件库用的是px单位,不是应该要考虑到跨端适配的问题吗?
前言
屏幕尺寸适配一直是移动web开发的大问题,在进行UI组件库的开发的时候,必然绕不过这个问题。不过,我想跳出组件库的范畴,从更广泛的角度谈一谈移动端屏幕尺寸适配。
流行多年的rem
基于rem的适配方案在数年前就已经兴起,并且一直沿用至今,较为系统的代表是淘宝的flexible 。 关于如何使用这套体系,前人之述备矣。我就不赘述了。 下面重点说一下我的使用体会。
适配与dpr无关
问题:在flexible体系当中引入dpr的概念,但是却又在代码中强制指定所有安卓的dpr都是1。如下代码片段。
为什么要这么做? 官方的说法是:当时安卓很多机型的dpr都是假的。参考这里
然而,我们从这儿也可以发现:即便设置的dpr与安卓机真实的dpr不同,但是适配方案仍然能正常工作。也就是说,设置的dpr与真实的dpr是否相等其实根本不影响此适配方案 我们还可以从源代码的另一方面来佐证这个结论。
发现没?其实本质上是先通过根元素的fontSize放大dpr倍,然后再通过viewport的scale缩小dpr倍,仅此而已。
既然dpr不影响适配,那么方案中为什么要引入它? 答案:是因为要同时解决“1px边框问题”和“高清图片问题”了,具体的可以参考这篇文章。
rem的弊端
flexible改变根元素的fontSize和viewport的scale,相当于js里面的改变了两个全局变量。那么我页面当中的所有其他元素都必须按照这个基准进行,这样我们在嵌入第三方内容的时候就会很不方便。比如:
天猫与淘宝
既然rem有一些问题,那么有替代方案吗?flexbox布局很早就出来了,迟迟不能广泛使用还是因为兼容性的问题。但是天猫已经率先使用了,可以参考如何看待手机天猫首页改用 flex 布局?与手机淘宝首页的 Rem 方案相比有何优缺点? 在回答”flexbox能否提到rem“这个问题之前,我仔细对比天猫的首页和淘宝的首页,会发现一些有趣的东西。 下图分别是iPhone5s和iPhone6p的对比图。(竖着排版对比不方便,建议把图片下载下来切换对比)
我们可以观察到一个现象: 对于天猫而言,6p比5s显示的内容显然要更多。对于淘宝而言,6p与5s显示的内容几乎是一样多。 为什么会这样呢?按理说这两个网站肯定都做到了适配的啊?
适配的标准
问题的答案在于:适配的标准不同。对于淘宝而言,当屏幕变大的时候,适配的效果是”按照比例放大“,元素的宽和高都按倍数增加,所以看到的内容一样多。对于天猫而言,当屏幕变大的时候,适配的效果不是”按照比例放大“,而是高度不变,宽度变化。所以可以看到更多的内容。两个标准都是可以接受的。如果是要做到第一个标准,则需要采取flexible方案,如果要做到第二个标准,则需要采取flexbox方案。
适配的原则
以前我们讨论响应式的标准的时候常常是这样考虑的:”当一个div在小屏幕是这么大的时候,那么在大屏幕下应该是多大呢?“但是,其实这种考虑是片面的。因为真实的需要考虑适配的场景往往不仅仅是div那么简单。比如这个div里面可能是文字,也可能是按钮,也可能是图片等等。我觉得有一个规则非常的好。
出处:http://www.ui001.com/article/123.html
举例:看刚才天猫的那个例子,中间那”十大金刚“,当屏幕变大的时候,它们只不过是相互之间的距离变大的,”金刚“入口本身的大小是没有发生改变的,这就是所谓的”控件弹性“。而淘宝则不是。上面的图片已经标注出了这种差异。
尾声
说来说去,还是那句话:”生命不息,折腾不止“。关于移动端适配,以后可能有更好的解决方案,但是可以预见的是,依旧会有新的问题冒出来。最近刚刚看了张鑫旭大大写的文章基于vw等viewport视区相对单位的响应式排版和布局,也许会成为未来流行的适配方案。