手机端自适应布局(自适应布局如何实现)

移动前端自适应解决方案和比较

大家好,又见面了,我是你们的朋友全栈君。一直在找有关手机端页面自适应写得比较好的文章,今天终于找到一篇,个人觉得写得很详细。如果想要拿到需求就知道要适用什么方法,除了要熟练规则、多参考一些优秀网站,还要动手实践几次。吐舌头






以下为转发的正文:




互联网上的自适应方案到底有几种呢?就我个人实践所知,有这么几种方案:




固定一个某些宽度,使用一个模式,加上少许的媒体查询方案


使用flexbox解决方案


使用百分比加媒体查询


使用rem


淘宝最近开源的一个框架和网易的框架有同工之异。都是采用rem实现一稿解决所有设置自适应。在没出来这种方案之前,第一种做法的人数也不少。类似以下说到的拉钩网。看一下流云诸葛的文章。




以下摘自:从网易与淘宝的font-size思考前端设计稿与工作流




1. 简单问题简单解决


我觉得有些web app并一定很复杂,比如拉勾网,你看看它的页面在iphone4,iphone6,ipad下的样子就知道了:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较




它的页面有一个特点,就是:




顶部与底部的bar不管分辨率怎么变,它的高度和位置都不变


中间每条招聘信息不管分辨率怎么变,招聘公司的图标等信息都位于条目的左边,薪资都位于右边


这种app是一种典型的弹性布局:关键元素高宽和位置都不变,只有容器元素在做伸缩变换。对于这类app,记住一个开发原则就好:
文字流式,控件弹性,图片等比缩放。以图描述:




手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较




这个规则是一套基本的适配规则,对于这种简单app来说已经足够,同时它也是后面要说的rem布局的基础。另外对于拉勾这种app可能需要额外媒介查询对布局进行调整的就是小屏幕设备。举例来说,因为现在很多设计稿是根据iphone6的尺寸来的,而iphon6设备宽的逻辑的像素是375px,而iphone4的逻辑像素是320个像素,所以如果你根据设计稿做出来的东西,在iphone4里面可能显示不下,比如说拉钩网底部那个下载框,你对比看下就知道了,这是4:






手机端页面的自适应设计的开发思路




6下面两边的间距比4多很多,说明拉勾对4肯定是做过适配的,从代码也可以证实这一点:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较




不过如果你拿到的是根据4的设计稿,那就没有问题,比4分辨率大的设备肯定能显示根据4的尺寸做出来的东西。




还有一点,这种情况css尺寸单位用px就好,不要用rem,避免增加复杂度。




2. 网易的做法


先来看看网易在不同分辨率下,呈现的效果:


手机端页面的自适应设计的开发思路


手机端页面的自适应设计的开发思路








从上面几张图可以看出,随着分辨率的增大,页面的效果会发生明显变化,主要体现在各个元素的宽高与间距。375*680的比320*680的导航栏明显要高。能够达到这种效果的根本原因就是因为网易页面里除了font-size之外的其它css尺寸都使用了rem作为单位,比如你看导航栏的高度设置代码:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较




可是在本文第1部分提到,使用rem布局结合在html上根据不同分辨率设置不同font-size有很多不好解决的麻烦,网易是如何解决的呢?
最根本的原因在于,网易页面上html的font-size不是预先通过媒介查询在css里定义好的,而是通过JS计算出来的,所以当分辨率发生变化时,html的font-size就会变,不过这得在你调整分辨率后,刷新页面才能看得到效果。
你看代码就知道为啥font-size是直接写到html的style上面的了(js设置的原因):




手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较




它是根据什么计算的,这就跟设计稿有关了,拿网易来说,它的设计稿应该是基于iphone4或者iphone5来的,所以它的设计稿竖直放时的横向分辨率为640px,为了计算方便,取一个100px的font-size为参照,那么body元素的宽度就可以设置为width: 6.4rem,于是html的font-size=deviceWidth / 6.4。这个deviceWidth就是viewport设置中的那个deviceWidth。根据这个计算规则,可得出本部分开始的四张截图中html的font-size大小如下:




deviceWidth = 320,font-size = 320 / 6.4 = 50px


deviceWidth = 375,font-size = 375 / 6.4 = 58.59375px


deviceWidth = 414,font-size = 414 / 6.4 = 64.6875px


deviceWidth = 500,font-size = 500 / 6.4 = 78.125px


事实上网易就是这么干的,你看它的代码就知道,body元素的宽是:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较




根据这个可以肯定它的设计稿竖着时的横向分辨率为640。然后你再看看网易在分辨率为320*680,375*680,414*680,500*680时,html的font-size是不是与上面计算的一致:




手机端页面的自适应设计的开发思路




这个deviceWidth通过document.documentElement.clientWidth就能取到了,所以当页面的dom ready后,做的第一件事情就是:




document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + ‘px’;


这个6.4怎么来的,当然是根据设计稿的横向分辨率/100得来的。下面总结下网易的这种做法:




(1)先拿设计稿竖着的横向分辨率除以100得到body元素的宽度:


如果设计稿基于iphone6,横向分辨率为750,body的width为750 / 100 = 7.5rem


如果设计稿基于iphone4/5,横向分辨率为640,body的width为640 / 100 = 6.4rem


(2)布局时,设计图标注的尺寸除以100得到css中的尺寸,比如下图:


手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较


播放器高度为210px,写样式的时候css应该这么写:height: 2.1rem。之所以取一个100作为参照,就是为了这里计算rem的方便!


(3)在dom ready以后,通过以下代码设置html的font-size:


document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + ‘px’;


6.4只是举个例子,如果是750的设计稿,应该除以7.5。


(4)
font-size可能需要额外的媒介查询,并且font-size不能使用rem
,如网易的设置:


复制代码


@media screen and (max-width:321px){



    .m-navlist{font-size:15px}


}




@media screen and (min-width:321px) and (max-width:400px){



    .m-navlist{font-size:16px}


}




@media screen and (min-width:400px){



    .m-navlist{font-size:18px}


}


复制代码


最后还有2个情况要说明:



第一,如果采用网易这种做法,要如下设置:


<meta name=”viewport” content=”initial-scale=1,maximum-scale=1, minimum-scale=1″>


第二,当deviceWidth大于设计稿的横向分辨率时,html的font-size始终等于横向分辨率/body元素宽:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较640*680




移动前端自适应解决方案和比较641*680




之所以这么干,是因为当deviceWidth大于640时,则物理分辨率大于1280(这就看设备的devicePixelRatio这个值了),应该去访问pc网站了。事实就是这样,你从手机访问网易,看到的是触屏版的页面,如果从pad访问,看到的就是电脑版的页面。如果你也想这么干,只要把总结中第三步的代码稍微改一下就行了:




var deviceWidth = document.documentElement.clientWidth;


if(deviceWidth > 640) deviceWidth = 640;

document.documentElement.style.fontSize = deviceWidth / 6.4 + ‘px’;


3. 淘宝的做法


看看淘宝在不同分辨率下,呈现的效果:




手机端页面的自适应设计的开发思路


手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较移动前端自适应解决方案和比较移动前端自适应解决方案和比较




淘宝的效果跟网易的效果其实是类似的,随着分辨率的变化,页面元素的尺寸和间距都相应变化,这是因为淘宝的尺寸也是使用了rem的原因。在介绍它的做法之前,先来了解一点关于viewport的知识,通常我们采用如下代码设置viewport:




<meta name=”viewport”   content=”width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no”>


这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:




设备的物理分辨率/(devicePixelRatio * scale),在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。




devicePixelRatio称为设备像素比,每款设备的devicePixelRatio都是已知,并且不变的,目前高清屏,普遍都是2,不过还有更高的,比如2.5, 3 等,我魅族note的手机的devicePixelRatio就是3。淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较在devicePixelRatio为2的时候,scale为0.5




移动前端自适应解决方案和比较在devicePixelRatio为3的时候,scale为0.3333




这么做目的当然是为了保证页面的大小与设计稿保持一致了,比如设计稿如果是750的横向分辨率,那么实际页面的device-width,以iphone6来说,也等于750,这样的话设计稿上标注的尺寸只要除以某一个值就能够转换为rem了。通过js设置viewport的方法如下:




var scale = 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:


手机端页面的自适应设计的开发思路




移动前端自适应解决方案和比较




接下来要解决的问题是,元素的尺寸该如何计算,比如说设计稿上某一个元素的宽为150px,换算成rem应该怎么算呢?这个值等于设计稿标注尺寸/该设计稿对应的html的font-size。拿淘宝来说的,他们用的设计稿是750的,所以html的font-size就是75,如果某个元素时150px的宽,换算成rem就是150 / 75 = 2rem。总结下淘宝的这些做法:




(1)动态设置viewport的scale


var scale = 1 / devicePixelRatio;


document.querySelector(‘meta[name=”viewport”]’).setAttribute(‘content’,’initial-scale=’ + scale + ‘, maximum-scale=’ + scale + ‘, minimum-scale=’ + scale + ‘, user-scalable=no’);


(2)动态计算html的font-size


document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + ‘px’;


(3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10


(4)font-size可能需要额外的媒介查询,并且font-size不使用rem,这一点跟网易是一样的。


最后还有一个情况要说明,跟网易一样,淘宝也设置了一个临界点,当设备竖着时横向物理分辨率大于1080时,html的font-size就不会变化了,原因也是一样的,分辨率已经可以去访问电脑版页面了。




手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较




移动前端自适应解决方案和比较




关于这种做法的具体实现,淘宝已经给我们提供了一个开源的解决方案,具体请查看:




https://github.com/amfe/lib-flexible




之前没有找到这相关的资料,实在不好意思:(




4. 比较网易与淘宝的做法


共同点:




都能适配所有的手机设备,对于pad,网易与淘宝都会跳转到pc页面,不再使用触屏版的页面


都需要动态设置html的font-size


布局时各元素的尺寸值都是根据设计稿标注的尺寸计算出来,由于html的font-size是动态调整的,所以能够做到不同分辨率下页面布局呈现等比变化


容器元素的font-size都不用rem,需要额外地对font-size做媒介查询


都能应用于尺寸不同的设计稿,只要按以上总结的方法去用就可以了


不同点




淘宝的设计稿是基于750的横向分辨率,网易的设计稿是基于640的横向分辨率,还要强调的是,虽然设计稿不同,但是最终的结果是一致的,设计稿的尺寸一个公司设计人员的工作标准,每个公司不一样而已


淘宝还需要动态设置viewport的scale,网易不用


最重要的区别就是:网易的做法,rem值很好计算,淘宝的做法肯定得用计算器才能用好了 。不过要是你使用了less和sass这样的css处理器,就好办多了,以淘宝跟less举例,我们可以这样编写less:


复制代码


//定义一个变量和一个mixin


@baseFontSize: 75;//基于视觉稿横屏尺寸/100得出的基准font-size


.px2rem(@name, @px){



    @{name}: @px / @baseFontSize * 1rem;


}


//使用示例:


.container {



    .px2rem(height, 240);


}


//less翻译结果:


.container {



    height: 3.2rem;


}


复制代码


5. 如何与设计协作


前端与设计师的协作应该是比较简单的,最重要的是要规范设计提供给你的产物,通常对于前端来说,我们需要设计师提供标注尺寸后的设计稿以及各种元素的切图文件,有了这些就可以开始布局了。考虑到Retina显示屏以及这么多移动设备分辨率却不一样的问题,那么设计师应该提供多套设计稿吗?从网易和淘宝的做法来看,应该是不用了,我们可以按照设计稿,先做出一套布局,按照以上方法做适配,由于是等比适配,所以各个设备的视觉效果差异应该会很小,当然也排除不了一些需要媒介查询特殊处理的情况,这肯定避免不了的。下面这张图是淘宝设计师分享的他们的工作流程:




手机端页面的自适应设计的开发思路


移动前端自适应解决方案和比较




解释一下就是:




第一步,视觉设计阶段,设计师按宽度750px(iphone 6)做设计稿,除图片外所有设计元素用矢量路径来做。设计定稿后在750px的设计稿上做标注,输出标注图。同时等比放大1.5倍生成宽度1125px的设计稿,在1125px的稿子里切图。




第二步,输出两个交付物给开发工程师:一个是程序用到的@3x切图资源,另一个是宽度750px的设计标注图。




第三步,开发工程师拿到750px标注图和@3x切图资源,完成iPhone 6(375pt)的界面开发。此阶段不能用固定宽度的方式开发界面,得用自动布局(auto layout),方便后续适配到其它尺寸。




第四步,适配调试阶段,基于iPhone 6的界面效果,分别向上向下调试iPhone 6 plus(414pt)和iPhone 5S及以下(320pt)的界面效果。由此完成大中小三屏适配。




注意第三步,就要使用我们以上介绍的网易跟淘宝的适配方法了。假如公司设计稿不是基于750的怎么办,其实很简单,按上图做一些相应替换即可,但是流程和方法还是一样的。解释一下为什么要在@3x的图里切,这是因为现在市面上也有不少像魅蓝note这种超高清屏幕,devicePixelRatio已经达到3了,这个切图保证在所有设备都清晰显示。




另外在加一句话在一般情况下的浏览器默认1rem=16px 这个之前的理解深度不够      正确的理解方法昨天请教了贾哥 1rem=1个html font-size px的大小  16px只是一般的浏览器设定的而已,千万不能理解为 1rem任何时候都是16px  按照贾哥的理解方式 正好可以请教为什么 根据屏幕/7.5 按750设计图    每个标签的大小都可以直接缩小100倍后用rem表示了




6. 总结


后来我们的项目决定使用网易使用的那种模式,看起来简单好用,淘宝的功能实现感觉很复杂 但是体验应该会更好,因为现在手机屏幕技术发展日新月异 2K 4K分辨率一部分手机也使用上了 还有前端设计方面有个默认的潜规则就是要依据IP6 或者IP5来设计尺寸 至于为什么不用安卓的手机?  我觉得应该是安卓的手机品牌众多 屏幕大小也很多 很难去决定设计哪一个 倒不如大家统一点一个IP6  也算是一个标准吧

————————————————————————————————————————————————————————————

有更好的方法和见解欢迎留言指出微笑

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127411.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月16日 下午10:00
下一篇 2022年4月16日 下午10:00


相关推荐

  • 解决使用IDE Run运行出错package pack/test is not in GOROOT (/usr/local/go/src/pack/test)

    解决使用IDE Run运行出错package pack/test is not in GOROOT (/usr/local/go/src/pack/test)首先先讲一下包包 package 是多个 Go 源码的集合 是一种高级的代码复用方案 Go 语言为我们提供了很多内置包 如 fmt os io 等 我们还可以根据自己的需要创建自己的包 一个包可以简单理解为一个存放 go 文件的文件夹 该文件夹下面的所有 go 文件都要在代码的第一行添加如下代码 声明该文件归属的包 package 包名注意事项 一个文件夹下面直接包含的文件只能归属一个 package 同样一个 package 的文件不能在多个文件夹下 包名可以不和文件夹的名字一样 包名不能包含 符号 包名

    2026年3月19日
    2
  • 常见MQTT服务器搭建

    常见MQTT服务器搭建简介MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它比较适合于在低带宽、不可靠的网络的进行远程传感器和控制设备通讯等,正在日益成为物联网通信协议的重要组成部分。MQTT现在主要用于即时通讯,物联网M2M,物联网采集等。本文就社区上常见的开源MQTT服务器在常见操作系统上的搭建做详细介绍。目前一些开源MQTT服…

    2022年6月11日
    70
  • 求原根_模12的原根

    求原根_模12的原根今天学了数论。。。求原根真的好暴力设模数为p我们把p−1p−1p-1分解质因数,对于每一个2≤i≤p−12≤i≤p−12\leqi\leqp-1,判断an−1pi%pan−1pi%pa^{n-1\overp_i}\%p是否为1,如果是,那么这个数就不是原根,否则就是ACCode#include&amp;amp;amp;lt;cstdio&amp;amp;amp;gt;#include&amp;amp;amp;lt;iostre

    2025年7月15日
    6
  • PHP之stripslashes()函数和htmlspecialchars()函数

    PHP之stripslashes()函数和htmlspecialchars()函数1 在进行表单验证中通常使用 stripslashes 函数对表单提交的数据进行处理 那么该函数是什么意思呢 nbsp stripslashes 函数用于清理字符串中的反斜杠 nbsp 与之相反的是 addslashes 函数 在字符串中的单引号 双引号 反斜杠 NULL 前面添加反斜杠 nbsp 通常默认的 php 会对所有的 GET POST 和 COOKIE 数据自动运行 addsl

    2026年3月26日
    2
  • 给你的PyCharm添加解释器

    给你的PyCharm添加解释器PyCharm 版本 PyCharm2020 2 很多同学在安装完 PyCharm 后 发现 PyCharm 并没有指定解释器 这样的代码就无法得到运行 此时我们需要手动添加解释器 进入添加解释器的有以下几种方法 1 右下角 解释器 gt 添加解释器 直接进入到添加 Python 解释器窗口 2 文件 gt 设置 gt 项目 gt Python 解释器 点击右侧设置按钮 选择添加 可进入到添加 Python 解释器窗口 添加 Python 解释器到达 Pytho

    2026年3月27日
    10
  • 干货精讲!java分布式事务框架

    干货精讲!java分布式事务框架事故背景公司最近安排了一波商品抢购活动 由于后台小哥操作失误最终导致活动效果差 被用户和代理商投诉了 经理让我带同事们一起复盘这次线上事故 什么原因造成的 抢购活动计划是零点准时开始 22 00 运营人员通过后台将商品上线 23 00 后台小哥已经将商品导入缓存中 提前预热抢购开始的瞬间流量非常大 按计划是通过 Redis 承担大部分用户查询请求 避免请求全部落在数据库上 如上图预期大部分请求会命中缓存 但是由于后台小哥预热缓存的时候将所有商品的缓存时间都设置为 2 小时过期 所有的商品在同一个时间点全

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号