H5|web移动前端自适应适配布局解决方案

 

方案:

  1. 固定一个某些宽度,使用一个模式,加上少许的媒体查询方案
  2. 使用flexbox解决方案
  3. 使用百分比加媒体查询
  4. 使用rem

1. 简单问题简单解决

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

imageimage

image

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

  • 顶部与底部的bar不管分辨率怎么变,它的高度和位置都不变
  • 中间每条招聘信息不管分辨率怎么变,招聘公司的图标等信息都位于条目的左边,薪资都位于右边

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

image

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

image

这是6:·

image

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

image

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

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

2. 网易的做法

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

imageimage

imageimage

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

image

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

原文来自http://caibaojian.com/mobile-responsive-example.html

它是根据什么计算的,这就跟设计稿有关了,拿网易来说,它的设计稿应该是基于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元素的宽是:

image

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

image320*680

image375*680

image414*680

image500*680

这个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中的尺寸,比如下图:
  • image
  • 播放器高度为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个情况要说明:

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

//code from http://caibaojian.com/mobile-responsive-example.html
<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">

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

image640*680

image641*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. 淘宝的做法

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

imageimageimage

淘宝的效果跟网易的效果其实是类似的,随着分辨率的变化,页面元素的尺寸和间距都相应变化,这是因为淘宝的尺寸也是使用了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动态设置:

image在devicePixelRatio为2的时候,scale为0.5

image在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:

image

接下来要解决的问题是,元素的尺寸该如何计算,比如说设计稿上某一个元素的宽为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就不会变化了,原因也是一样的,分辨率已经可以去访问电脑版页面了。

image

image

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

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显示屏以及这么多移动设备分辨率却不一样的问题,那么设计师应该提供多套设计稿吗?从网易和淘宝的做法来看,应该是不用了,我们可以按照设计稿,先做出一套布局,按照以上方法做适配,由于是等比适配,所以各个设备的视觉效果差异应该会很小,当然也排除不了一些需要媒介查询特殊处理的情况,这肯定避免不了的。下面这张图是淘宝设计师分享的他们的工作流程:

image

解释一下就是:

第一步,视觉设计阶段,设计师按宽度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了,这个切图保证在所有设备都清晰显示。

6. 总结

这篇文章对我来说价值也很大,今后做html5的项目就有思路了,本文提到的三种方法将来肯定都有用武之地。

 

转载 https://blog.csdn.net/qq_34020571/article/details/78923089

转载于:https://www.cnblogs.com/liuranRan/p/11178066.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转] 用Diff和Patch工具维护源码

在Unix系统下&#xff0c;维护源码版本可以使用很多方法&#xff0c;其中最常用的当然是大名鼎鼎的CVS&#xff0c;但实际上&#xff0c;简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具&#xff0c;Unix标配中的diff和patch工具就完全可以完成代码的简单备份和…

[html] 当页面中使用application/xhtml+xml会出现什么问题吗?

[html] 当页面中使用application/xhtmlxml会出现什么问题吗&#xff1f; 要求比较严格&#xff0c;必须有head、body标签且每个元素必须是关闭的。一些老的浏览器不支持&#xff0c;实际上&#xff0c;任何最新的浏览器都将支持application/xhtmlxml媒体类型。大多数浏览器也接…

html5 本地保存大数据库,HTML5本地储存 - jellydd的个人空间 - OSCHINA - 中文开源技术交流社区...

传统方式我们用document.cookie来储存&#xff0c;但是储存大小较小&#xff0c;而且解析复杂&#xff0c;HTML5提出新的解决方案&#xff0c;使用sessionStorage和localStorage存储数据。localStorage&#xff1a;1. 永久生效2. 多窗口共享3. 容量大约为20M◆window.localStor…

[html] H5的Web Storage带来什么好处?

[html] H5的Web Storage带来什么好处&#xff1f; 存储的数据量更大&#xff0c;可以达到 5M&#xff1b;减少不必要的数据请求&#xff0c;不会自动把数据发送给服务器localStorage 可以把数据永久保存在本地&#xff0c;除非显示的清除或删除数据支持事件通知机制API 更加方便…

「BZOJ2654」tree

「BZOJ2654」tree 最小生成树二分答案。 最开始并没有觉得可以二分答案&#xff0c;因为答案并不单调啊。 其实根据题意&#xff0c;白边的数目肯定大于need条&#xff0c;而最小生成树的白边数并不等于need&#xff08;废话&#xff09;&#xff0c;可以二分将每条白边的权值m…

jQuery 结合 Json 提交数据到Webservice,并接收从Webservice返回的Json数据

简单的Json数据提交 jQuery ajax webservice&#xff1a;get 和 post 一、GET 方式客户端代码vardata { classCode: "0001"}; //这里要直接使用JOSN对象$.ajax({ type: "GET", contentType: "application/json; chars…

html服务器框架,一种类似http/html的分布式GUI程序设计框架

笔者构想了一种类似http/html的分布式GUI程序设计框架&#xff0c;适用于WIndows、桌面Linux、Mac OS以及C&#xff0c;Java&#xff0c;Python等多种支持GUI编程的程序设计系统。但是对于手机小屏幕&#xff0c;可能不合适。本系统包括窗口描述规则;gui.exe -- 一个命令行程序…

X86逆向教程10:学会使用硬件断点

本节课我们将学习硬件断点的使用技巧&#xff0c;硬件断点是由硬件提供给我们的一组寄存器&#xff0c;我们可以对这些硬件寄存器设置相应的值&#xff0c;然后让硬件帮我们断在需要下断点的地址上面&#xff0c;这就是硬件断点&#xff0c;硬件断点依赖于寄存器&#xff0c;这…

PHP获取IP的多种方式解析

转自&#xff1a;http://developer.51cto.com/art/200911/164514.htm PHP获取IP的方法有许多种&#xff0c;我们今天向大家总结了六种方法&#xff0c;希望通过对这六种方法的学习&#xff0c;能够加深我们对PHP语言的进一步了解&#xff0c;巩固我们所掌握的知识。 PHP获取IP方…

html 监控键盘,后台监控鼠标和键盘(可监听全局的鼠标以及键盘按键)

资源下载此资源下载价格为3D币&#xff0c;请先登录资源文件列表MouseKeyboardLibrary/MouseKeyboardLibrary/app.config , 134MouseKeyboardLibrary/MouseKeyboardLibrary/bin/Debug/MouseKeyboardLibrary.exe , 23040MouseKeyboardLibrary/MouseKeyboardLibrary/bin/Debug/Mo…

SQL优化34条

我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习、摘录、并汇总部分资料与大家分享&#xff01;&#xff08;1&#xff09; 选择最有效率的表名顺序(只在基于规则的优化器中有效)&#xff1a;ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名&#xff…

POJ 3258 River Hopscotch

题目链接&#xff1a;https://vjudge.net/problem/POJ-3258 题目大意 给定数轴上一个起点 0&#xff0c;终点 L&#xff0c;以及中间 N 个不同的点&#xff0c;现准备删除中间 N 个点中的 M 个&#xff0c;使得剩下来的点&#xff08;包括起点和终点&#xff09;&#xff0c;相…

2021泉州高考学校成绩查询,2021泉州市地区高考成绩排名查询,泉州市高考各高中成绩喜报榜单...

距离2018年高考还有不到一个月的时间了&#xff0c;很多人在准备最后冲刺的同时&#xff0c;也在关心高考成绩。2018各地区高考成绩排名查询,高考各高中成绩喜报榜单尚未公布&#xff0c;下面是往年各地区高考成绩排名查询,高考各高中成绩喜报榜单&#xff0c;想要了解同学可以…

转载:CEO如何“养好CIO同时管好CIO”?

http://www.enet.com.cn/article/2010/1214/A20101214800028.shtml 在现代企业经营理论中&#xff0c;有个着名的“二八定律”&#xff0c;即人才对企业贡献而言&#xff0c;常常是20%的人做出了80%的企业效益。显而易见&#xff0c;这“20%”就是企业的骨干与核心。而这“20%”…

PL/SQL中模拟EBS上下文

有时&#xff0c;我们需要查询的表或视图&#xff0c;是具有OU屏蔽的&#xff0c;这时我们就需要模拟EBS中的上下文来实现查询数据。 BEGIN fnd_global.apps_initialize(user_id >1,resp_id > 2,resp_appl_id >3); mo_global.init(ONT); END; 上述参数的获取&#xff…

[html] 一般习惯把js写在</body>前,但有例外的情况吗?说说看

[html] 一般习惯把js写在前&#xff0c;但有例外的情况吗&#xff1f;说说看 js的放置位置有三种&#xff1a; &#xff08;1&#xff09;放在head标签内 &#xff08;2&#xff09;放在body标签内 &#xff08;3&#xff09;外部script个人简介 我是歌谣&#xff0c;欢迎和大…

计算机桌面设计总结及体会,计算机基础学习心得

计算机基础学习心得 相关内容:计算机硬件是指计算机系统中由电子&#xff0c;机械和光电元件等组成的各种物理装置的总称。下面是第一范文网带来的计算机硬件实习心得体会&#xff0c;欢迎欣赏。计算机硬件实习心得体会一&#xff1a;一、实习目的&#xff1a;1、练习和巩固识别…

POJ 2676 Sudoku【DancingLinks,数独】

http://poj.org/problem?id2676POJ 2676 Sudoku也是求解规模为9*9的数独问题&#xff0c;与POJ 3074 Sudoku相同的问题&#xff0c;只是修改了输入输出格式而已。。。所以也不废话了&#xff0c;嘿嘿。。。 #include<stdio.h> #include<string.h> const int MAX_C…

Unittest方法 -- 测试固件(TestFixture)

前置和后置 1.setUp&#xff1a;在写测试用例的时候&#xff0c;每次操作其实都是基于打开浏览器输入对应网址这些操作&#xff0c;这个就是执行用例的前置条件。2.tearDown&#xff1a;执行完用例后&#xff0c;为了不影响下一次用例的执行&#xff0c;一般有个数据还原的过程…

[html] 如何关闭HTML页面在IOS下的键盘首字母自动大写?

[html] 如何关闭HTML页面在IOS下的键盘首字母自动大写&#xff1f;&#xff1f; autocapitalize"none"或"off"个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一…