翻页H5全分辨率适配最佳实践

全分辨率适配是移动开发的一个永恒的话题,因为很多开发者只能做到“打折扣”的全适配,也就是用手头上的几个手机测试过,某些机型完美,某些机型略有缺陷,总体上马马虎虎过得去,就交工了。

全分辨率适配做的最好的我认为就是易企秀等H5平台,毕竟专业的就是不一样。今天我整理一下他们的最佳实践,当然,他们也会有过时的或者不健全的实践方式,只要我能发现,我定然会指出。

基础知识

首先请访问我的文章《通俗讲解CSS pixels、device pixels、device-width、layout viewport、visual viewport、ideal viewport六个概念》,了解一下基本概念。

另外我参考了https://isux.tencent.com/how-to-make-webpage-fit-screen.html ,不过注意,它并不是说翻页H5的,而是任意H5,所以只有部分内容可以借鉴。

最佳体验

我认为,凡是谈最佳实践,就要先定下最优结果。面向最优结果的实践才可能是最佳实践。那么全分辨率适配的最优结果或者说叫最佳体验是什么呢?

  • 当手机大小不同、视口宽高比例相同,那么两者的体验差别就应该像是放大缩小版的关系一样。思路:利用<meta name="viewport" content="width=device-width, initial-scale=xxxx, maximum-scale=xxxx, user-scalable=no">和背景图的background-position: 50% 50%; background-size: cover; background-origin: content-box;来解决,详细见下文。

  • 当手机大小不同,视口宽高比例也不同,那么除了放大缩小的关系,还有一些区别:比较矮的视口,它的背景图的上下边缘被裁剪的就多一点,比较瘦高的视口,它的背景图的上下边缘被裁剪的就少一点。思路:见下文。

屏幕分辨率的讨论

根据百度流量研究院的统计,安卓端和ios端的分辨率占有率如下:

安卓端

先说安卓,1080x1920的占有率虽然很高而且还在涨,但是720x1280也属于很高的分辨率了,而且手机端屏幕小、像素密度大,所以720x1280的图片显示在1080x1920分辨率下也不会有太大问题,安卓端我们暂时以720x1280为准。

iOS端

再说iOS,1242x2208是iPhone 6S PLUS的分辨率,是目前最高的分辨率,而且它份额也在涨。虽然话是这么说了,也由于手机端屏幕小、像素密度大,所以按照750x1334制图也不会有什么问题的。iOS端我们暂时以750x1334为准。

再对比一下,720x1280比750x1334的数字看起来更容易记,所以就720x1280吧。

以上并不是玄学或者胡乱估算,而是按720x1280作为主流分辨率就确实够用了。

那么问题来了,易企秀以什么为基准分辨率呢?易企秀是基于iPhone 5的640宽度的,因为易企秀毕竟是从iPhone5时代创立的。到今天这个宽度已经不适用了,安卓很少有这个分辨率,iOS虽然有这个分辨率,但是从百度统计来看,是一路走低的。所以,我们坚持我们的720宽度就好了。

Paste_Image.png

视口分辨率的研究

上文虽然说按照720x1280作为主流分辨率,但是又有一个现实就是,视口大小是小于屏幕整体大小的,因为浏览器一般都有地址栏和工具栏,微信还好一点,只有地址栏,但都会占有一些面积。我调查了一些手机的微信视口,如下:

iPhone 6S PLUS的微信浏览器的视口分辨率,是414x672,比例是0.616:1
iPhone 6S是375x603,比例是0.622:1
红米Note 4是360x572,比例是0.63:1
OPPO R7是360x527,比例是0.68:1

到底设什么尺寸作为背景图的标准尺寸才好呢?这需要先了解一下背景图CSS的相关知识。

直接说答案,参考了https://isux.tencent.com/how-to-make-webpage-fit-screen.html之后你就会知道,background-position: 50% 50%; background-size: cover; background-origin: content-box;是翻页H5的背景图的最佳方案。这些代码保证了背景图是从中心点向周围铺开的,而且cover的特点是:考察自身宽高比例与div的宽高比例,照顾其中一者保持相等,然后另一者会在屏幕外溢出。

Paste_Image.png

然后我们看看易企秀又是怎么做的。首先易企秀确实用了上一段的代码,然后我从他们作品的主背景图的尺寸看,他们用的是640x1008的背景图,把640x1008的背景图对应到720宽度是720x1134。这个尺寸是不是科学呢?

720x1134比例是0.635:1,也就是说,背景图在某些视口下是上下溢出,也有一些是左右溢出,上下溢出的概率很大,只有在很瘦的视口下,比如iPhone 6S PLUS里,会有略微的左右溢出。

我们分别分析一下上下被裁剪跟左右被裁剪导致的问题:

  • 上下被裁剪导致的问题主要是浮动元素跟背景图上下错位。这个问题很容易解决,下文有介绍,我们先看左右被裁减。

  • 左右被裁剪也会导致一些问题,就是浮动元素跟背景图比例失调,也就是说,不仅错位,而且比例尺不一致。这个问题就很麻烦,当视口很瘦高,比如iPhone6S PLUS的微信浏览器看页面,背景图会被左右裁剪,这样会导致背景图跟浮动元素无法严格匹配,也就是背景图只露出了中间的一部分,而浮动元素还是全宽显示,这样浮动元素就显得比背景图大,而且某些靠边的浮动元素也会被裁剪。总体说,左右被裁减导致的问题更加严重,上下被裁剪导致的问题很轻。解决左右被裁剪没有根本的办法,只能是不要出现这种情况。

所以结论是:
要么,设计师按照720x1170作为画布面积,把它当做标准网页面积来制图。
要么,设计师按照720x1134作为画布面积,把它当做标准网页面积来制图,导致的某些瘦视口里浮动元素偏大,某些靠边的浮动元素也会被裁剪,这些问题只好忍了。

综上,我建议选用720x1170作为画布面积。以下方案按照720x1170为例。

viewport元数据的写法

最著名的viewport元数据是<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">,然而,如果我们想实现“等比放大缩小”的最佳实践,那么这条最著名的声明其实是不适用的。原因是:

假设我们使用了这个声明,那么iPhone 5的css像素宽度是320px,iPhone6是375px,这时候,假设iPhone 5一行能写20个汉字,那么iPhone 6一行就能写23个汉字,这下就不符合“等比放大缩小”的关系了,大手机的字没见到大,只见到了大手机一行多写了3个字。

那么为什么这条看似不科学的声明还那么流行呢?因为它适用于普通手机网页。翻页H5与普通手机网页有本质区别:

  • 翻页H5要实现等比放大缩小,普通手机网页不需要实现这种效果。
  • 普通手机网页追求的是:字体在各个手机上看起来必须视觉大小一致,不需要管一行写20个字还是23个字。而翻页H5不追求大小一致,追求的是每行统一写20个字,所以大手机的字允许看起来稍大一点,小手机的字允许看着偏小一点。
  • 翻页H5的高度必须是视口的高度,普通手机网页不必,所以普通网页一行写几个字、写几行都随便,翻页H5则不可以这么随便。

所以,翻页H5的viewport的元数据应该怎么声明?易企秀的例子是(iPhone 6 plus下):<meta name="viewport" id="viewport" content="width=320, initial-scale=1.29375, maximum-scale=1.29375, user-scalable=no">,它的原理是:

写死width=320,然后由js动态计算scale。js必须紧贴<meta name="viewport" id="viewport">,保证在body显示之前修改元数据。

    <meta name="viewport" id="viewport" content="width=320, initial-scale=1, maximum-scale=1, user-scalable=no">
    <script>
      var initialscale = document.documentElement.clientWidth / 320;
      document.getElementById('viewport').content = 'width=320, initial-scale=' + initialscale +
        ', maximum-scale=' + initialscale + ', user-scalable=no';
    </script>

页面制作的过程

开发预览环境

开发预览环境可以有多种,通常有三种:

一、上策:可以用PC版网页,预览环境就是PC浏览器,然后配合device.js判断设备类型,这需要你先研究这个js库,用起来很简单。然后加入下方这段代码即可。这个方案可以直接作为PC端和平板端的适配方案。

html.desktop body, html.tablet body {
    margin: 0 auto;
    height: 520px;
}
body {
    height: 100%;
}

你问520px是怎么来的?因为背景图高度是1170px,然后1170 * 320 / 720 = 520px。为什么320x520是理想分辨率?因为我们在这个分辨率下开发,才能保证浮动元素的top、left值是准确的。

二、中策:可以用手机预览。需要给手机hosts文件做配置,指向你的电脑本地服务器的虚拟域名。缺点就是麻烦、调试困难。

三、下策:可以用chrome自带的device mode切换到iPhone 5模式开发,因为iPhone 5的视口宽度就是320px。但是有一个问题是chrome的device mode不可以动态调整高度,而真实世界的浏览器视口高度是多种多样的,尤其是我们应该在320x520的理想分辨率下开发,这就是它是下策的原因。这个方式只可用于测试手机特有的功能,不应该用来测量top和left值。

涉及到设计师的问题

设计师要按照720x1170的画布来设计,但是设计师要注意小视口的可能性。因为一些手机在使用非微信浏览器,也就是浏览器既有地址栏又有工具栏的时候,它视口很矮,另外翻页H5的上方一般有一个音乐播放按钮,下方一般要加一个小箭头,所以设计师要做到“留天留地”,在上方下方不要放主要元素,尤其是不要放LOGO和标题。

我建议主要内容都放在上下居中的720x1000的范围内即可,一定不要越界。

分页的处理

分页的容器的id我命名方式为page1、page2...或者其他规则都可以。

分页里的浮动元素主要有图片和文本段,先覆盖一下样式:

.page {
    position: relative;
    width: 100%;
    height: 100%;
    background-position: 50% 50%;
    background-size: cover;
    background-origin: content-box;
}
    <div class="page" id="page1">
      <div style="position: absolute; top: ...; left: ...;" id="imgbox1-1">浮动元素</div>
      <div style="position: absolute; top: ...; left: ...;" id="txtbox1-1">浮动元素</div>
    </div>

浮动元素的处理

浮动元素定位问题

开发的时候,浮动元素要在父元素里绝对定位,top和left的单位用px。

topleft的值是怎么得来的?

是在上述的三种开发环境下,通过F12 devtools微调,最后调出来的。注意,虽然top和left可以让设计师帮你测量出来,但其实没必要,因为测量出来的值是设备像素,之后你还要换算成我们写css用的css pixels。所以通过F12工具微调,视觉上大致没问题就可以了。

当把开发好的页面用手机预览的时候你会发现图片跟背景图错位了,因为背景图的上下边缘有裁剪,按照裁剪之后的高度来定位浮动图片的话,图片肯定会全部往下错位。怎么办?

解决方案:我们给浮动元素们包裹一个relative属性的父元素,比如叫div.editarea,Emmet表示为div.page>div.editarea>浮动元素们。注意,背景图是设在div.page身上的,不要给.editarea设背景图。然后给这个元素再加一个class叫.editarea-offset,让.editarea-offsettop等于calc((100% - 520px) / 2),它是一个负值,就是被裁减的厚度值,这样浮动元素们的向下的错位就被向上拉动,也就是修正了。

.editarea-offset {
    top: calc((100% - 520px) / 2);
}

什么时候不需要加这个.editarea-offset修正呢?比如,现在有个浮动元素,它内部不含图片,或者它虽然含图片,但不要跟背景图对位,现在我要求它必须占据100%视口高度,且不可溢出,这种情况下就不需要加.editarea-offset

这种情况一般是出现在只包含纯文字且文字很多的元素。这种情况下我们当然希望它尽可能占据最大面积,显示最多的文字,比如我打算在页面顶部放一个大标题,下面放列表,项目有很多,局部滚动。就如:

<div class="xxlist">
<h1>大标题</h1>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
...
</ul>
</div>

现在我想让.xxlist的高度尽可能高,达到100%高度,然后ul也尽量高,局部内容滚动,所以不能写死ul的height值,这时候height的正确姿势是:

ul {
    height: calc(100% - 32px);
}

也就是说,h1的容器高度是32px的话,ul的高度就calc计算一下,就好了。

浮动图片宽高问题

浮动元素的图片都是按照720x1170画布的前提下设计的,所以需要先算出相对于320x520的css像素宽高,然后才能写入代码里。这个运算让sass自己去算就行了。也就是:

  • 先看设计师发过来的图片的宽高,先如实抄到代码里。比如设计师给你的图就是23px的宽度,就抄23px。这个23px是设备像素。下一步我们把设备像素换算成css像素。
  • 比如你的width: 123px这样子的代码,应该写成width: round(123px * 320 / 720),也就是写成round(123px * 4 / 9)。sass编译的时候会自动帮你计算。高度值也是一样处理。

浮动文字的字号和行高问题

字体跟图片的处理是一样的道理,字号单位并不用什么高深的rem,直接用px即可。当然,用rem和em都是可以的。

比如:

.page .txtbox {
  position: absolute;
  font-size: 16px;
  line-height: 1.414;
}

.page p {
  display: inline-block;
  margin: 0;
  padding: 0;
}

#txtbox1-1 {
  top: 380px;
  left: 68px;
}

#txtbox1-1 p {
  font-size: 1em;
  color: #fff;
}

注意,不要给p元素设宽度,因为inline-block就可以保证宽度自适应,而且加动画之后,比如加中心放大的动画,可以确保中心点正确。

本文只为介绍适配,适配大致就是这些内容,至于怎么真正做出一个翻页H5,那就是本文之外的内容了。以后会写。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容