热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Flexible实现手淘H5页面的终端适配

转发自大漠老师的文章由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开

转发自大漠老师的文章


由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。vw的兼容方案可以参阅《如何在Vue项目中使用vw实现移动端适配》一文。


曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时代可以跟这些麻烦说拜拜。可没想到到了移动时代,为了处理各终端的适配而乱了手脚。对于混迹各社区的偶,时常发现大家拿手机淘宝的H5页面做讨论——手淘的H5页面是如何实现多终端的适配

那么趁此Amfe阿里无线前端团队双11技术连载之际,用一个实战案例来告诉大家,手淘的H5页面是如何实现多终端适配的,希望这篇文章对大家在Mobile的世界中能过得更轻松。


目标

拿一个双11的Mobile页面来做案例,比如你实现一个类似下图的一个H5页面:

Flexible实现手淘H5页面的终端适配

目标很清晰,就是做一个这样的H5页面。


DEMO

请用手机扫下面的二维码

DEMO


痛点

虽然H5的页面与PC的Web页面相比简单了不少,但让我们头痛的事情是要想尽办法让页面能适配众多不同的终端设备。看看下图你就会知道,这是多么痛苦的一件事情:

Flexible实现手淘H5页面的终端适配

点击这里查看更多终端设备的参数。

再来看看手淘H5要适配的终端设备数据:

Flexible实现手淘H5页面的终端适配

看到这些数据,是否死的心都有了,或者说为此捏了一把汗出来。


手淘团队适配协作模式

早期移动端开发,对于终端设备适配问题只属于Android系列,只不过很多设计师常常忽略Android适配问题,只出一套iOS平台设计稿。但随着iPhone6,iPhone6+的出现,从此终端适配问题不再是Android系列了,也从这个时候让移动端适配全面进入到“杂屏”时代。

Flexible实现手淘H5页面的终端适配

上图来自于paintcodeapp.com

为了应对这多么的终端设备,设计师和前端开发之间又应该采用什么协作模式?或许大家对此也非常感兴趣。

而整个手淘设计师和前端开发的适配协作基本思路是:



  • 选择一种尺寸作为设计和开发基准

  • 定义一套适配规则,自动适配剩下的两种尺寸(其实不仅这两种,你懂的)

  • 特殊适配效果给出设计效果

还是上一张图吧,因为一图胜过千言万语:

Flexible实现手淘H5页面的终端适配

在此也不做更多的阐述。在手淘的设计师和前端开发协作过程中:手淘设计师常选择iPhone6作为基准设计尺寸,交付给前端的设计尺寸是按750px * 1334px为准(高度会随着内容多少而改变)。前端开发人员通过一套适配规则自动适配到其他的尺寸。

根据上面所说的,设计师给我们的设计图是一个750px * 1600px的页面:

Flexible实现手淘H5页面的终端适配


前端开发完成终端适配方案

拿到设计师给的设计图之后,剩下的事情是前端开发人员的事了。而手淘经过多年的摸索和实战,总结了一套移动端适配的方案——flexible方案

这种方案具体在实际开发中如何使用,暂时先卖个关子,在继续详细的开发实施之前,我们要先了解一些基本概念。


一些基本概念

在进行具体实战之前,首先得了解下面这些基本概念(术语):


视窗 viewport

简单的理解,viewport是严格等于浏览器的窗口。在桌面浏览器中,viewport就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。

移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:虚拟的viewportvisualviewport和布局的viewportlayoutviewport。

George Cummins在Stack Overflow上对这两个基本概念做了详细的解释。

而事实上viewport是一个很复杂的知识点,上面的简单描述可能无法帮助你更好的理解viewport,而你又想对此做更深的了解,可以阅读PPK写的相关教程。


物理像素(physical pixel)

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。

Flexible实现手淘H5页面的终端适配


设备独立像素(density-independent pixel)

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。


CSS像素

CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs。


屏幕密度

屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。


设备像素比(device pixel ratio)

设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

在Javascript中,可以通过window.devicePixelRatio获取到当前设备的dpr。而在CSS中,可以通过-webkit-device-pixel-ratio-webkit-min-device-pixel-ratio-webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

dip或dp,(device independent pixels,设备独立像素)与屏幕密度有关。dip可以用来辅助区分视网膜设备还是非视网膜设备。

缩合上述的几个概念,用一张图来解释:

Flexible实现手淘H5页面的终端适配

众所周知,iPhone6的设备宽度和高度为375pt * 667pt,可以理解为设备的独立像素;而其dpr为2,根据上面公式,我们可以很轻松得知其物理像素为750pt * 1334pt

如下图所示,某元素的CSS样式:

在不同的屏幕上,CSS像素所呈现的物理尺寸是一致的,而不同的是CSS像素所对应的物理像素具数是不一致的。在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。

有关于更多的介绍可以点击这里详细了解。

看到这里,你能感觉到,在移动端时代屏幕适配除了Layout之外,还要考虑到图片的适配,因为其直接影响到页面显示质量,对于如何实现图片适配,再此不做过多详细阐述。这里盗用了@南宮瑞揚根据mir.aculo.us翻译的一张信息图:

Flexible实现手淘H5页面的终端适配


meta标签


标签有很多种,而这里要着重说的是viewport的meta标签,其主要用来告诉浏览器如何规范的渲染Web页面,而你则需要告诉它视窗有多大。在开发移动端页面,我们需要设置meta标签如下:

代码以显示网页的屏幕宽度定义了视窗宽度。网页的比例和最大比例被设置为100%。

留个悬念,因为后面的解决方案中需要重度依赖meta标签。


CSS单位rem

在W3C规范中是这样描述rem的:


font size of the root element.


简单的理解,rem就是相对于根元素font-size来做计算。而我们的方案中使用rem单位,是能轻易的根据font-size计算出元素的盒模型大小。而这个特色对我们来说是特别的有益处。


前端实现方案

了解了前面一些相关概念之后,接下来我们来看实际解决方案。在整个手淘团队,我们有一个名叫lib-flexible的库,而这个库就是用来解决H5页面终端适配的。


lib-flexible是什么?

lib-flexible是一个制作H5适配的开源库,可以点击这里下载相关文件,获取需要的Javascript和CSS文件。

当然你可以直接使用阿里CDN:

将代码中的{{version}}换成对应的版本号0.3.4


使用方法

lib-flexible库的使用方法非常的简单,只需要在Web页面的中添加对应的flexible_css.js,flexible.js文件:

第一种方法是将文件下载到你的项目中,然后通过相对路径添加:

或者直接加载阿里CDN的文件:

另外强烈建议对JS做内联处理,在所有资源加载之前执行这个JS。执行这个JS后,会在元素上增加一个data-dpr属性,以及一个font-size样式。JS会根据不同的设备添加不同的data-dpr值,比如说2或者3,同时会给html加上对应的font-size的值,比如说75px

如此一来,页面中的元素,都可以通过rem单位来设置。他们会根据html元素的font-size值做相应的计算,从而实现屏幕的适配效果。

除此之外,在引入lib-flexible需要执行的JS之前,可以手动设置meta来控制dpr值,如:

其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,因为在Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr1


flexible的实质

flexible实际上就是能过JS来动态改写meta标签,代码类似这样:

事实上他做了这几样事情:



  • 动态改写标签

  • 元素添加data-dpr属性,并且动态改写data-dpr的值

  • 元素添加font-size属性,并且动态改写font-size的值


案例实战

了解Flexible相关的知识之后,咱们回到文章开头。我们的目标是制作一个适配各终端的H5页面。别的不多说,动手才能丰衣足食。


创建HTML模板

正如前面所介绍的一样,首先加载了Flexible所需的配置:

这个时候可以根据设计的图需求,在HTML文档的中添加对应的HTML结构,比如:

这仅是一个示例文档,大家可以根据自己风格写模板

为了能更好的测试页面,给其配置一点假数据:

接下来的工作就是美化工作了。在写具体样式之前,有几个点需要先了解一下。


把视觉稿中的px转换成rem

读到这里,大家应该都知道,我们接下来要做的事情,就是如何把视觉稿中的px转换成rem。在此花点时间解释一下。

首先,目前日常工作当中,视觉设计师给到前端开发人员手中的视觉稿尺寸一般是基于640px750px以及1125px宽度为准。甚至为什么?大家应该懂的(考虑Retina屏)。

正如文章开头显示的示例设计稿,他就是一张以750px为基础设计的。那么问题来了,我们如何将设计稿中的各元素的px转换成rem

Flexible实现手淘H5页面的终端适配

我厂的视觉设计师想得还是很周到的,会帮你把相关的信息在视觉稿上标注出来

目前Flexible会将视觉稿分成100份(主要为了以后能更好的兼容vhvw),而每一份被称为一个单位a。同时1rem单位被认定为10a。针对我们这份视觉稿可以计算出:

那么我们这个示例的稿子就分成了10a,也就是整个宽度为10rem对应的font-size75px

Flexible实现手淘H5页面的终端适配

这样一来,对于视觉稿上的元素尺寸换算,只需要原始的px值除以rem基准值即可。例如此例视觉稿中的图片,其尺寸是176px * 176px,转换成为2.346667rem * 2.346667rem


如何快速计算

在实际生产当中,如果每一次计算px转换rem,或许会觉得非常麻烦,或许直接影响大家平时的开发效率。为了能让大家更快进行转换,我们团队内的同学各施所长,为px转换rem写了各式各样的小工具。


CSSREM

CSSREM是一个CSS的px值转rem值的Sublime Text3自动完成插件。这个插件是由@正霖编写。先来看看插件的效果:

Flexible实现手淘H5页面的终端适配

有关于CSSREM如何安装、配置教程可以点击这里查阅。


CSS处理器

除了使用编辑器的插件之外,还可以使用CSS的处理器来帮助大家处理。比如说Sass、LESS以及PostCSS这样的处理器。我们简单来看两个示例。


Sass

使用Sass的同学,可以使用Sass的函数、混合宏这些功能来实现:

除了使用Sass函数外,还可以使用Sass的混合宏:

有关于更多的介绍,可以点击这里进行了解。


PostCSS(px2rem)

除了Sass这样的CSS处理器这外,我们团队的@颂奇同学还开发了一款npm的工具px2rem。安装好px2rem之后,可以在项目中直接使用。也可以使用PostCSS。使用PostCSS插件postcss-px2rem:

除了在Gulp中配置外,还可以使用其他的配置方式,详细的介绍可以点击这里进行了解。

配置完成之后,在实际使用时,你只要像下面这样使用:

px2rem处理之后将会变成:

在整个开发中有了这些工具之后,完全不用担心px值转rem值影响开发效率。


文本字号不建议使用rem

前面大家都见证了如何使用rem来完成H5适配。那么文本又将如何处理适配。是不是也通过rem来做自动适配。

显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px24px,所以我们不希望出现13px和15px这样的奇葩尺寸

如此一来,就决定了在制作H5的页面中,rem并不适合用到段落文本上。所以在Flexible整个适配方案中,考虑文本还是使用px作为单位。只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小。

为了能更好的利于开发,在实际开发中,我们可以定制一个font-dpr()这样的Sass混合宏:

有了这样的混合宏之后,在开发中可以直接这样使用:

当然这只是针对于描述性的文本,比如说段落文本。但有的时候文本的字号也需要分场景的,比如在项目中有一个slogan,业务方希望这个slogan能根据不同的终端适配。针对这样的场景,完全可以使用rem给slogan做计量单位。


CSS

本来想把这个页面的用到的CSS(或SCSS)贴出来,但考虑篇幅过长,而且这么简单的页面,我想大家也能轻而易举搞定。所以就省略了。权当是给大家留的一个作业吧,感兴趣的可以试试Flexible能否帮你快速完成H5页面终端适配。


效果

最后来看看真机上显示的效果吧。我截了两种设备下的效果:


iPhone4

Flexible实现手淘H5页面的终端适配


iPhone6+

Flexible实现手淘H5页面的终端适配


总结

其实H5适配的方案有很多种,网上有关于这方面的教程也非常的多。不管哪种方法,都有其自己的优势和劣势。而本文主要介绍的是如何使用Flexible这样的一库来完成H5页面的终端适配。为什么推荐使用Flexible库来做H5页面的终端设备适配呢?主要因为这个库在手淘已经使用了近一年,而且已达到了较为稳定的状态。除此之外,你不需要考虑如何对元素进行折算,可以根据对应的视觉稿,直接切入。

当然,如果您有更好的H5页面终端适配方案,欢迎在下面的评论中与我们一起分享。如果您在使用这个库时,碰到任何问题,都可以在Github给我们提Issue。我们团队会努力解决相关需Issues。



推荐阅读
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • 如何优化Webpack打包后的代码分割
    本文介绍了如何通过优化Webpack的代码分割来减小打包后的文件大小。主要包括拆分业务逻辑代码和引入第三方包的代码、配置Webpack插件、异步代码的处理、代码分割重命名、配置vendors和cacheGroups等方面的内容。通过合理配置和优化,可以有效减小打包后的文件大小,提高应用的加载速度。 ... [详细]
author-avatar
牛涛fd_501
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有