今天推荐的是知乎一个优秀的问答,文章牵扯到很多理论性的东西,各自有各自的观点,具体问题具体分析,如果想学到知道的可以话五分钟认真读完这篇文章,也许会给你带来一些不错的认知
1:本文建议读者不要使用flexible
或者其他修改viewport
致使viewport width
不等于device-width
的方案(因为这会导致一些bug
)
2:本文建议读者不要使用以rem
或者小程序rpx
来实现等比缩放为主的布局手段,而使用面向逻辑像素px
为主,面向等比缩放的vx
和vxxx(vw/vh/vmax/vmin)
为辅助的布局单位,搭配一些flex
等布局手段
3:本文建议读者一般情况遵循:同样观看距离情况下,大屏看的更多而不是大屏看的更大的设计最佳实践来进行布局,并且以这种最佳实践作为理论依据来传递给设计师(当然你觉得等比缩放才是合理的,请看其他回答,该回答不适合你)
4:本文没有鼓吹读者使用响应式布局,也没有鼓吹读者盲目忽略兼容性使用vx和vxxx
,同时也没有反对读者使用rem
这个单位本身原有的定义来实现一些布局
5:评论前请仔细阅读并理解本文内容,以免出现为了对话不在同一个频道的情况
你们老是鼓吹rem
的,醒醒吧,别再看网上大片大片的rem
文章
flexible
方案已经废坑了,已经废坑了,已经废坑了
对,flexible
已经不维护了,原因自己看flexible的github
px
没有问题,用rem
来实现自适应才有问题(因为它是vx,vxxx
单位的备胎),能问这种问题的人,应该认真研究一下viewport
。
ppi(pixel per inch)
每英寸像素,指的是屏幕在每英寸的物理像素,更高的ppi
意味着屏幕的清晰度更佳。所谓高分屏,其实就是指ppi
大于同类设备的屏幕。比如对于桌面设备,大于96ppi
。对于移动设备,大于160ppi
所谓视网膜屏,其实就是指在该观看距离内超出人类的辨认能力的屏幕。比如对于桌面设备,大于192ppi
。
对于移动设备大于326ppi
,对于移动设备而言,一般来说ppi
以160为一个档次也就是假设一个ppi160
,2寸x3寸的屏幕,物理像素应该是320x480
。同理ppi320
,同样尺寸的屏幕,物理像素是640x960由于它们尺寸一致,假设它们观看距离一致,那么消除掉ppi的影响,他们的逻辑像素是一致的也就是逻辑像素长度 = 物理像素长度 * 160 / ppi
得出都是 320 x 480
当然,由于生产标准不一致,不可能做到绝对的160ppi
作为标准,所以ppi
的等级划分是动态的
dpr (device point ratio / device pixel ratio)
渲染像素与逻辑像素的比例。由于渲染像素一般等于逻辑像素,如果ppi
是以160为基准的话,那么 dpr = ppi / 160
多少倍屏或者多少x(三倍屏,3x
,意思就是3dpr
),一般来说就是说的是这个值
viewport
像素又是什么,它本质是DIP(Device Independent Pixels)
,中文意思设备无关像素,是与上述所有像素都无绝对逻辑关系的一个单位。其实是浏览器内部对逻辑像素进行再处理的结果,简单来理解就是调整逻辑像素的缩放来达到适应设备的一个中间层对于pc,viewport
是不生效的,所以在pc上,px其实就是逻辑像素(chrome)
。但是逻辑像素是与软件实现有关的,所以会出现一些问题。比如在win
上,对于部分国产马甲浏览器,viewport
内部没有适配系统的缩放等级,导致渲染的内容过小
head
设置width=device-width
的viewport
css
中使用px
flex
布局,或者配合vw
进行自适应viewport width=device-width
是什么意思,其实就是让viewport
的尺寸等于逻辑像素的尺寸那么你可能会问,那什么方案才是合理的?当然我说了这么多,你还是觉得等比是合理的,我没话说。
我以为,合理的适应方案,是px
+各种布局手段为主,vx,vxxx
+媒体查询为辅的方案,因为上面也说了,px
是跟逻辑像素挂钩的,而逻辑像素反映的是同样观看距离设备的屏幕尺寸。既然手机和平板是同样观看距离的设备,那么,可以简单理解为,逻辑像素就等同于物理尺寸(厘米分米那种单位)
一个合理的视觉产品,难道是人去调整观看距离而固定物理尺寸的?而不是固定观看范围而调整调整屏幕尺寸的?举个极端例子,电影院怎么不放一台手机去播电影,让观众都凑到屏幕前面看?
那么用逻辑像素来进行布局,会是什么样的效果。
逻辑像素布局,元素的物理尺寸是几乎一致的,但是在不同屏幕下看到的总体比例是不同的。这回导致一些结果,就是大屏手机看的更多
至于rem方案,除了盖楼的兄弟说的问题,还有会导致富文本显示错误,你想想,你把viewport
改了迁就rem来实现vw
,那么你页面的viewport
像素就会不正常甚至异常,富文本里边如果使用了px
,那么px就会变小,富文本的内容会变得小的无法看,除非你家的富文本编辑器是自己实现的或者使用iframe
,不然没法解决
放眼看vw
已经可以在移动端浏览器大规模使用了,这也是flexible
方案不维护的主要原因,所以rem
这个备胎应该早就下舞台了
但是可恶的是网上还有大规模鼓吹rem
甚至还有说0202还在用px
的言论,简直心寒
普遍认为响应式就是以媒体查询做为解决方案的手段,而其他都是自适应
自适应和响应式可以同时存在
个人认为,自适应应该只存在于一个同一类设备中,而不存在pc/手机适应,原因刚才也说了
声明一下,本人并不是鼓吹读者使用响应式而不用自适应,那些拿响应式开发效率不高来吐槽的朋友消停一下,看清楚我表达的意思
自适应,是应该实现的,比如a
手机和b
手机之间就应该采用自适应。因为他们的逻辑像素跟屏幕尺寸差别不大,交互方式差别也不大。自适应是成本比较低的方案
但是,即使我们需要自适应,但不代表我们需要vw
,甚至是rem
,那是两码事,实现自适应的方案还有很多,远古时代的流式布局,还有现代的flex
,都可以给前端作为参考。
vx,vxxx
布局很麻烦,但我相信rem
其实也很麻烦。px2rem
?为什么要使用px
来转rem
?那如果我真想用px
这个单位的时候怎么办?容我深思,emmmm…``
所以我实现了一个 rdp-loader
的方案,为啥叫rdp(relative device point)
,因为我也想不到还有什么单位没用上了
在这里不知羞耻的放出源码,写的有些随意(因为我懒!!),你们写的应该比我好,大神轻拍
const r = /([\d.]+)rdp/g
const loaderlltils = require('loader-utils');
const defaultOptions = {
useRpx: false,
size: 375
}
module.exports = function(content){
this.cacheable();
const options = {
...defaultOptions,
...(loaderlltils.getOptions(this) || {})
}
const rpxDPI = 2
const rpxSize = 375
// 750 / 100
// 375 * 2 / 100 / 2
return content.replace(r, (_,number) => {
return options.useRpx ?
`${(+number) * rpxSize * rpxDPI / options.size }rpx'
: '${((+number) / (options.size / 100)).toFixed(5)}vmin`
})
}
这个webpack loader
可以嵌入小程序或者web mobile
进行开发,使用逻辑像素的写法就可以转换成vmin
或者rpx
其中参数两个,useRpx
,在小程序使用,size
,就是设计稿的基准逻辑像素
当我想用等比缩放的布局的时候,我就用rdp
,如果我想使用基于逻辑像素布局的时候就用px
,全程无缝切换
.elem {
/* 使用等比缩放 */
width: 100rdp;
/* 使用逻辑像素 */
width: 100px;
}
同理,在rn的实现
export function rdp(size:number){
return Dimensions.get("window").width/375*size;
}
虽然我是提供了vx,vxxx
的方案,但注意一点,什么时候使用vx,vxxx
的布局方案
我建议是,几乎不用,实际上,暂时为止,我也想不到什么场景是必须使用等比缩放的情况
在更多的时候,我们应该使用flex
或者定位配合百分比等方案来处理
当然vx,vxxx
是可以无缝转换rem
的项目的,作为面向viewport
和px
不习惯或者不喜欢的朋友,可以作为一个过渡方案
就像flexible github
废弃后大篇幅提供了vx,vxxx
的兼容处理方案一样,很多人也会误读,以为vx,vxxx
是银弹
希望vx,vxxx
不要成为下一个rem
,希望大家为viewport
和px
正名
欢迎关注我