当前位置: 首页 > Web前端 > HTML

(淘宝无限改编)手机端REM布局详解(转载非原创)

时间:2023-04-02 23:24:44 HTML

从网易和淘宝的font-size思考前端设计稿和工作流程思考学习size属性,讨论html5设计稿的大小和前端与设计的协作过程。内容很多,但一定对你的技术和工作有价值。欢迎阅读和评论:)。这是淘宝的github网址,里面有适配需要的js和文档地址:https://github.com/amfe/lib-f...问题是看了白书的博文导致的《移动web资源整理》最近,他在博文中的一段话中指出,如果html5要适配各种分辨率的移动设备,就应该使用rem这样的尺寸单位,同时给出了在html上设置font-size的代码对于每个分辨率范围:复制代码html{font-size:10px}@mediascreenand(min-width:321px)and(max-width:375px){html{font-size:11px}}@mediascreenand(min-width:376px)and(max-width:414px){html{font-size:12px}}@mediascreenand(min-width:415px)and(max-width:639px){html{font-size:15px}}@mediascreenand(min-width:640px)and(max-width:719px){html{font-size:20px}}@mediascreenand(min-width:720px)and(max-width:749px){html{font-size:22.5px}}@mediascreenand(min-width:750px)and(max-width:799px){html{font-size:23.5px}}@mediascreenand(min-width:800px){html{font-size:25px}}复制代码在实际项目中,与元素大小相关的css,如width、height、line-height、margin、padding等,都在rem,使页面在不同设备下网页布局保持一致。比如一个网页有一个.item类,宽度设置为3.4rem。该类在不同分辨率下的实际宽度如下:复制代码321px<=device-width<=375px,font-size:11px-->widthof.item:34px376px<=device-width<=414px,font-size:12px--->.item的宽度:37.4px415px<=device-width<=639px,font-size:15px--->.item的宽度:40.8px640px<=device-width<=719px,font-size:20px--->.item的宽度:51px720px<=device-width<=749px,font-size:22.5px--->.item的宽度:76.5px750px<=device-width<=799px,font-size:23.5px--->.item的宽度:79.8999999px800px<=device-width,font-size:25px--->.itemwidth:85px复制代码上面的代码乍一看还不错,这不就是响应式设计应该做的吗?但是考虑到工作量和复杂度,它有以下缺点:(1).item类的宽度在所有设备下都是3.4rem,但是不同分辨率下实际像素是不一样的,所以在某些分辨率下,界面效果宽度可能不合适。它可能太宽或太窄。这时候就需要调整宽度。那么,就需要编写媒体查询代码了。设计一个rem值。不过这里的mediaquery有7种,css中有很多size相关的属性。不确定哪个属性不适合哪个分辨率范围。最终,会导致编写大量的媒体查询来适应所有设备。而且写的时候rem要根据某个分辨率html的font-size来计算,这个计算不一定每次都那么容易,比如40px/23.5px,这个rem值是计算不出来的!由此可见麻烦有多大。(2)上面代码给出的7个范围下的font-size可能不合适,这7个范围也不一定合适。其实可能没有那么多,所以找出这几个范围,每个范围最合适的font-size也是很麻烦的(3)设计稿上标注了resolution。前端将设计稿中每个元素的像素大小转换成rem时,应该以哪个font-size为标准呢??需要写作才能知道。也正是因为上面提到的不足,我觉得这种适配方式不是特别好,写起来也太麻烦了。为了完成工作,我们需要找到更简单、更有效的方法。那么html5应该如何适配众多的移动设备呢?我目前知道的有3种解决方案,将在下面的第2、3和4部分中进行解释。如果大家阅读后有什么想法,欢迎在评论中与我交流。简单的问题和简单的解决方案我觉得有些webapp不一定很复杂,比如拉勾网,你可以看看它的页面在iphone4、iphone6、ipad下是怎样的:imageimageimage它的页面有一个特点,就是:top而无论底部bar的分辨率如何变化,其高度和位置都不会发生变化典型的弹性布局:关键元素的高度、宽度和位置保持不变,只有容器元素在缩放。对于这类app,最好记住一个开发原则:文字流转、控制灵活、图片按比例缩放。一张图描述:imagerule是一套基本的适配规则,对于这个简单的app来说已经足够了,也是后面要讲的rem布局的基础。此外,对于拉钩等应用,可能需要额外的媒体查询来调整小屏幕设备的布局。比如,因为很多设计稿都是基于iphone6的尺寸,而iphone6设备的逻辑像素宽度是375px,而iphone4的逻辑像素是320像素,所以如果你根据设计稿做东西,在iphone4中可能无法显示。比如拉勾网底部的下载框,对比一下就可以看到。Thisis4:imageandthisis6:image6的两边距离比4大很多,也就是说拉钩必须为4做的。已经适配了,这个也可以从中确认code:image但是如果你拿到的是基于4的设计稿,那就没有问题了。分辨率大于4的设备肯定能显示按照4尺寸制作的东西。还有一点,在这种情况下,最好使用px作为css大小单位而不是rem,以避免增加复杂度。网易的做法下面看看网易在不同分辨率下的效果:宽度和高度以及间距。375680明显高于320680导航栏。能达到这个效果的根本原因是网易页面上除了font-size以外的所有css尺寸都是以rem为单位的。比如可以看到导航栏的高度设置代码:image在本文第一部分有提到。使用rem布局结合在html上根据不同的分辨率设置不同的font-size有很多麻烦不好解决。网易是怎么解决的?最根本的原因是网易页面的html的font-size不是通过mediaquery预先定义在css中的,而是js计算出来的,所以当分辨率改变的时候,html的font-size也会改变,但是你有调整分辨率后刷新页面查看效果。看代码就知道为什么font-size直接写在html的style上了(js设置的原因):什么是基于图片的计算,跟设计稿有关系。以网易为例,它的设计稿应该是基于iphone4或者iphone5的,所以它的设计稿竖放时水平分辨率为640px。为了计算方便,以font-size为100px作为参考,那么body元素的宽度可以设置为width:6.4rem,所以html的font-size=deviceWidth/6.4。这个deviceWidth就是viewport设置中的deviceWidth。根据这个计算规则,可以得出这部分开头的四个截图中html的font-size为:deviceWidth=320,font-size=320/6.4=50pxdeviceWidth=375,font-size=375/6.4=58.59375pxdeviceWidth=414,font-size=414/6.4=64.6875pxdeviceWidth=500,font-size=500/6.4=78.125px其实网易就是这么干的,可以看它的代码,width的body元素为:imageaccordingto这可以确定其设计稿的水平分辨率在垂直时为640。然后可以看看当网易分辨率为320680、375680、414680、500680时,html的font-size是否与上面的计算一致:image320*680image375*680image414*680image500*680,deviceWidth是通过document.documentElement传递的。clientWidth是可以获取到的,所以当页面的dom准备好后,首先要做的是:document.documentElement.style.fontSize=document.documentElement.clientWidth/6.4+'px';这个6.4是怎么来的,当然是根据设计稿的水平分辨率/100推导出来的。总结一下网易的做法:(1)将设计稿的垂直水平分辨率除以100得到body元素的宽度:如果设计稿是基于iphone6,水平分辨率为750,body宽度为750/100=7.5rem如果设计稿是基于iphone4/5,横向分辨率为640,机身宽度为640/100=6.4rem(2)layout时,将设计图标注的尺寸划分绘制100得到css中的大小,比如下图:图片播放器的高度为210px。写样式的时候css应该这样写:height:2.1rem。之所以以100为参考,是为了这里计算rem方便!(3)dom准备好后,通过以下代码设置html的font-size:document.documentElement.style.fontSize=document.documentElement.clientWidth/6.4+'px';6.4只是一个例子,如果是750的设计稿,应该除以7.5。(4)font-size可能需要额外的媒体查询,font-size不能使用rem,比如网易的设置:复制代码@mediascreenand(max-width:321px){.m-navlist{font-size:15px}}@mediascreenand(min-width:321px)and(max-width:400px){.m-navlist{font-size:16px}}@mediascreenand(min-width:400px){.m-navlist{font-size:18px}}复制代码最后分两种情况说明一下:第一,如果采用网易的话,viewport应该设置如下:二、当deviceWidth大于设计稿水平分辨率时,html的font-size始终等于水平分辨率/body元素宽度:image640*680image641*680这是因为当deviceWidth大于640时,物理分辨率大于1280(这个取决于设备的devicePixelRatio的值),应该访问pc网站。这是事实。当您通过手机访问网易时,您将看到该页面的触摸屏版本。如果您从平板电脑访问它,您将看到该页面的计算机版本。如果你想做同样的事情,只需更改摘要中第三步中的代码:vardeviceWidth=document.documentElement.clientWidth;if(deviceWidth>640)deviceWidth=640;document.documentElement.style.fontSize=deviceWidth/6.4+'px';淘宝的做法看淘宝在不同分辨率下的效果:imageimageimage淘宝的效果其实和网易差不多.随着分辨率的变化,页面元素的大小和间距也不同。相应改变,这是因为淘宝的大小也是使用rem的原因。在介绍它的方法之前,我们先了解一下viewport。通常,我们使用如下代码来设置视口:这样,当整个网页在设备中显示时,页面宽度将等于设备的逻辑像素大小,即device-width。这个device-width的计算公式是:设备的物理分辨率/(devicePixelRatio*scale),当scale为1时,device-width=设备的物理分辨率/devicePixelRatio。devicePixelRatio称为设备像素比。每个设备的devicePixelRatio已知且不变。目前高清屏一般都是2,但是也有更高的,比如2.5、3等,我的魅族note手机devicePixelRatio是3。淘宝触屏版布局的前提是viewport的scale是根据devicePixelRatio动态设置的:当image为devicePixelRatio为2时,scale为0.5image为当devicePixelRatio为3时,scale为0.3333这样做的目的当然是为了保证页面的尺寸和设计稿一致。比如设计稿的横向分辨率为750,那么实际页面的device-width,对于iphone6而言,也等于750。此时设计稿上标注的尺寸可以换算为将其除以某个值。雷姆。通过js设置视口的方法如下:varscale=1/devicePixelRatio;document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale='+scale+',maximum-scale='+scale+',minimum-scale='+scale+',user-scalable=no');淘宝布局的第二个关键点是html元素的font-size的计算公式,font-size=deviceWidth/10:image接下来要解决的问题就是如何计算元素的大小。比如设计稿上一个元素的宽度是150px,应该怎么换算成rem呢?这个值等于设计稿的尺寸/设计稿对应的html的font-size。以淘宝为例,他们用的设计稿是750,所以html的font-size是75,如果某个元素是150px宽,换算成rem就是150/75=2rem。总结一下淘宝的这些做法:(1)动态设置viewport的scalevarscale=1/devicePixelRatio;document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale='+scale+',maximum-scale='+scale+',minimum-scale='+scale+',user-scalable=no');(2)动态计算字体大小htmldocument.documentElement.style.fontSize=document.documentElement.clientWidth/10+'px';(3)布局时,每个元素的css大小=设计稿标签大小/设计稿横向分辨率/10(4)font-size可能需要额外的mediaquery,font-size没有使用rem,是一样的作为网易。最后,还有一种情况需要说明。和网易一样,淘宝也设置了一个临界点。当设备竖直时设备水平物理分辨率大于1080时,html的font-size不会改变。道理是一样的。您已经可以访问计算机版本页面。imageimage关于这种方式的具体实现,淘宝已经给我们提供了开源方案。详情请查看:https://github.com/amfe/lib-f...之前没有找到这方面的相关资料,实在抱歉:(比较网易和淘宝的做法,共同点:都可以适配所有移动设备。对于pad,网易和淘宝都会跳转到PC页面,不再使用触屏版页面,需要动态设置html的字体-size中各个元素的大小值layout是按照设计稿标注的尺寸计算的,由于html的font-size是动态调整的,所以可以实现不同分辨率下的页面布局呈现比例变化,容器元素Rem的font-不是size需要,font-size需要额外mediaquery,可以适用于不同尺寸的设计稿,只要按照上面总结的方法使用即可。不同的是淘宝的设计稿是基于一个水平分辨率750。网易的设计稿是基于水平分辨率640的。还要强调的是,虽然设计稿不同,但最终的结果是一样的。设计稿的大小是一个公司设计师的工作标准,每个公司都不一样。淘宝也需要动态设置视口的比例。网易和网易最大的区别是:网易的方法,rem值很容易计算,而淘宝的方法必须要用计算器才能用。但是如果使用less和sass等CSS处理器处理起来就容易多了。以淘宝和less为例,我们可以这样写less:复制代码//定义一个变量和一个mixin@baseFontSize:75;//基于视觉稿横屏尺寸基准/100font-size.px2rem(@name,@px){@{name}:@px/@baseFontSize*1rem;}//使用示例:.container{.px2rem(height,240);}//less翻译结果:.container{height:3.2rem;}复制代码如何与设计协同前端和设计师的协同应该比较简单,最重要的是将设计提供给你的产品标准化,通常前端需要设计师提供尺寸设计稿和各元素的裁剪文件,您可以根据这些文件开始布局。考虑到Retina显示屏和这么多移动设备的不同分辨率,设计师是否应该提供多套设计稿?从网易和淘宝的做法来看,应该是没有必要的。我们可以先根据设计稿做一套布局,按照上面的方法进行适配。既然是等比例适配,每个设备的视觉效果差异应该是不一样的。非常小,当然不能排除一些需要对媒体查询进行特殊处理的情况,这肯定是无法避免的。下图是淘宝设计师分享的他们的工作流程:image解释如下:第一步,视觉设计阶段,设计师制作宽度为750px(iPhone6)的设计稿,除图片外的所有设计元素均使用矢量图路径做到这一点。设计定稿后,在750px的设计稿上进行标注,并输出标注图。同时将比例放大1.5倍生成宽度为1125px的设计稿,图片在1125px的草稿中裁剪。第二步,向开发工程师输出两个交付物:一个是程序使用的@3x切图资源,一个是宽750px的设计标注图。第三步,开发工程师拿到750px标注图和@3x切图资源,完成iPhone6(375pt)的界面开发。现阶段无法开发固定宽度的界面,必须使用自动布局,方便后续适配其他尺寸。第四步是适配调试阶段。在iPhone6界面效果的基础上,将iPhone6plus(414pt)和iPhone5S及以下(320pt)的界面效果分别向上和向下调整。这样就完成了大中小三屏适配。注意第三步是使用我们上面介绍的网易和淘宝适配的方法。如果公司的设计稿不是基于750怎么办,其实很简单,按照上图做一些相应的替换即可,但是流程和方法还是一样的。解释一下为什么要在@3x的图片里切。这是因为市面上有很多像魅族note这样的超高清屏幕。devicePixelRatio达到了3,这张切图保证在所有设备上都能清晰显示。总结终于写完文章了,希望大家还是满意的,这篇文章对我也有很大的价值,以后对html5项目会有想法,本文提到的三种方法一定会在future两者各有用途。最后,欢迎大家在评论中和我分享对这篇文章的看法,我们一起交流,共同进步。https://www.cnblogs.com/well-…