翻頁H5全分辨率適配最佳實踐

全分辨率適配是移動開發(fā)的一個永恒的話題,因為很多開發(fā)者只能做到“打折扣”的全適配,也就是用手頭上的幾個手機(jī)測試過,某些機(jī)型完美,某些機(jī)型略有缺陷,總體上馬馬虎虎過得去,就交工了。

全分辨率適配做的最好的我認(rèn)為就是易企秀等H5平臺,畢竟專業(yè)的就是不一樣。今天我整理一下他們的最佳實踐,當(dāng)然,他們也會有過時的或者不健全的實踐方式,只要我能發(fā)現(xiàn),我定然會指出。

基礎(chǔ)知識

首先請訪問我的文章《通俗講解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,所以只有部分內(nèi)容可以借鑒。

最佳體驗

我認(rèn)為,凡是談最佳實踐,就要先定下最優(yōu)結(jié)果。面向最優(yōu)結(jié)果的實踐才可能是最佳實踐。那么全分辨率適配的最優(yōu)結(jié)果或者說叫最佳體驗是什么呢?

  • 當(dāng)手機(jī)大小不同、視口寬高比例相同,那么兩者的體驗差別就應(yīng)該像是放大縮小版的關(guān)系一樣。思路:利用<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;來解決,詳細(xì)見下文。

  • 當(dāng)手機(jī)大小不同,視口寬高比例也不同,那么除了放大縮小的關(guān)系,還有一些區(qū)別:比較矮的視口,它的背景圖的上下邊緣被裁剪的就多一點,比較瘦高的視口,它的背景圖的上下邊緣被裁剪的就少一點。思路:見下文。

屏幕分辨率的討論

根據(jù)百度流量研究院的統(tǒng)計,安卓端和ios端的分辨率占有率如下:

安卓端

先說安卓,1080x1920的占有率雖然很高而且還在漲,但是720x1280也屬于很高的分辨率了,而且手機(jī)端屏幕小、像素密度大,所以720x1280的圖片顯示在1080x1920分辨率下也不會有太大問題,安卓端我們暫時以720x1280為準(zhǔn)。

iOS端

再說iOS,1242x2208是iPhone 6S PLUS的分辨率,是目前最高的分辨率,而且它份額也在漲。雖然話是這么說了,也由于手機(jī)端屏幕小、像素密度大,所以按照750x1334制圖也不會有什么問題的。iOS端我們暫時以750x1334為準(zhǔn)。

再對比一下,720x1280比750x1334的數(shù)字看起來更容易記,所以就720x1280吧。

以上并不是玄學(xué)或者胡亂估算,而是按720x1280作為主流分辨率就確實夠用了。

那么問題來了,易企秀以什么為基準(zhǔn)分辨率呢?易企秀是基于iPhone 5的640寬度的,因為易企秀畢竟是從iPhone5時代創(chuàng)立的。到今天這個寬度已經(jīng)不適用了,安卓很少有這個分辨率,iOS雖然有這個分辨率,但是從百度統(tǒng)計來看,是一路走低的。所以,我們堅持我們的720寬度就好了。

Paste_Image.png

視口分辨率的研究

上文雖然說按照720x1280作為主流分辨率,但是又有一個現(xiàn)實就是,視口大小是小于屏幕整體大小的,因為瀏覽器一般都有地址欄和工具欄,微信還好一點,只有地址欄,但都會占有一些面積。我調(diào)查了一些手機(jī)的微信視口,如下:

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

到底設(shè)什么尺寸作為背景圖的標(biāo)準(zhǔn)尺寸才好呢?這需要先了解一下背景圖CSS的相關(guān)知識。

直接說答案,參考了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的背景圖對應(yīng)到720寬度是720x1134。這個尺寸是不是科學(xué)呢?

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

我們分別分析一下上下被裁剪跟左右被裁剪導(dǎo)致的問題:

  • 上下被裁剪導(dǎo)致的問題主要是浮動元素跟背景圖上下錯位。這個問題很容易解決,下文有介紹,我們先看左右被裁減。

  • 左右被裁剪也會導(dǎo)致一些問題,就是浮動元素跟背景圖比例失調(diào),也就是說,不僅錯位,而且比例尺不一致。這個問題就很麻煩,當(dāng)視口很瘦高,比如iPhone6S PLUS的微信瀏覽器看頁面,背景圖會被左右裁剪,這樣會導(dǎo)致背景圖跟浮動元素?zé)o法嚴(yán)格匹配,也就是背景圖只露出了中間的一部分,而浮動元素還是全寬顯示,這樣浮動元素就顯得比背景圖大,而且某些靠邊的浮動元素也會被裁剪??傮w說,左右被裁減導(dǎo)致的問題更加嚴(yán)重,上下被裁剪導(dǎo)致的問題很輕。解決左右被裁剪沒有根本的辦法,只能是不要出現(xiàn)這種情況。

所以結(jié)論是:
要么,設(shè)計師按照720x1170作為畫布面積,把它當(dāng)做標(biāo)準(zhǔn)網(wǎng)頁面積來制圖。
要么,設(shè)計師按照720x1134作為畫布面積,把它當(dāng)做標(biāo)準(zhǔn)網(wǎng)頁面積來制圖,導(dǎo)致的某些瘦視口里浮動元素偏大,某些靠邊的浮動元素也會被裁剪,這些問題只好忍了。

綜上,我建議選用720x1170作為畫布面積。以下方案按照720x1170為例。

viewport元數(shù)據(jù)的寫法

最著名的viewport元數(shù)據(jù)是<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">,然而,如果我們想實現(xiàn)“等比放大縮小”的最佳實踐,那么這條最著名的聲明其實是不適用的。原因是:

假設(shè)我們使用了這個聲明,那么iPhone 5的css像素寬度是320px,iPhone6是375px,這時候,假設(shè)iPhone 5一行能寫20個漢字,那么iPhone 6一行就能寫23個漢字,這下就不符合“等比放大縮小”的關(guān)系了,大手機(jī)的字沒見到大,只見到了大手機(jī)一行多寫了3個字。

那么為什么這條看似不科學(xué)的聲明還那么流行呢?因為它適用于普通手機(jī)網(wǎng)頁。翻頁H5與普通手機(jī)網(wǎng)頁有本質(zhì)區(qū)別:

  • 翻頁H5要實現(xiàn)等比放大縮小,普通手機(jī)網(wǎng)頁不需要實現(xiàn)這種效果。
  • 普通手機(jī)網(wǎng)頁追求的是:字體在各個手機(jī)上看起來必須視覺大小一致,不需要管一行寫20個字還是23個字。而翻頁H5不追求大小一致,追求的是每行統(tǒng)一寫20個字,所以大手機(jī)的字允許看起來稍大一點,小手機(jī)的字允許看著偏小一點。
  • 翻頁H5的高度必須是視口的高度,普通手機(jī)網(wǎng)頁不必,所以普通網(wǎng)頁一行寫幾個字、寫幾行都隨便,翻頁H5則不可以這么隨便。

所以,翻頁H5的viewport的元數(shù)據(jù)應(yīng)該怎么聲明?易企秀的例子是(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動態(tài)計算scale。js必須緊貼<meta name="viewport" id="viewport">,保證在body顯示之前修改元數(shù)據(jù)。

    <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>

頁面制作的過程

開發(fā)預(yù)覽環(huán)境

開發(fā)預(yù)覽環(huán)境可以有多種,通常有三種:

一、上策:可以用PC版網(wǎng)頁,預(yù)覽環(huán)境就是PC瀏覽器,然后配合device.js判斷設(shè)備類型,這需要你先研究這個js庫,用起來很簡單。然后加入下方這段代碼即可。這個方案可以直接作為PC端和平板端的適配方案。

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

你問520px是怎么來的?因為背景圖高度是1170px,然后1170 * 320 / 720 = 520px。為什么320x520是理想分辨率?因為我們在這個分辨率下開發(fā),才能保證浮動元素的top、left值是準(zhǔn)確的。

二、中策:可以用手機(jī)預(yù)覽。需要給手機(jī)hosts文件做配置,指向你的電腦本地服務(wù)器的虛擬域名。缺點就是麻煩、調(diào)試?yán)щy。

三、下策:可以用chrome自帶的device mode切換到iPhone 5模式開發(fā),因為iPhone 5的視口寬度就是320px。但是有一個問題是chrome的device mode不可以動態(tài)調(diào)整高度,而真實世界的瀏覽器視口高度是多種多樣的,尤其是我們應(yīng)該在320x520的理想分辨率下開發(fā),這就是它是下策的原因。這個方式只可用于測試手機(jī)特有的功能,不應(yīng)該用來測量top和left值。

涉及到設(shè)計師的問題

設(shè)計師要按照720x1170的畫布來設(shè)計,但是設(shè)計師要注意小視口的可能性。因為一些手機(jī)在使用非微信瀏覽器,也就是瀏覽器既有地址欄又有工具欄的時候,它視口很矮,另外翻頁H5的上方一般有一個音樂播放按鈕,下方一般要加一個小箭頭,所以設(shè)計師要做到“留天留地”,在上方下方不要放主要元素,尤其是不要放LOGO和標(biāo)題。

我建議主要內(nèi)容都放在上下居中的720x1000的范圍內(nèi)即可,一定不要越界。

分頁的處理

分頁的容器的id我命名方式為page1、page2...或者其他規(guī)則都可以。

分頁里的浮動元素主要有圖片和文本段,先覆蓋一下樣式:

.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>

浮動元素的處理

浮動元素定位問題

開發(fā)的時候,浮動元素要在父元素里絕對定位,top和left的單位用px。

topleft的值是怎么得來的?

是在上述的三種開發(fā)環(huán)境下,通過F12 devtools微調(diào),最后調(diào)出來的。注意,雖然top和left可以讓設(shè)計師幫你測量出來,但其實沒必要,因為測量出來的值是設(shè)備像素,之后你還要換算成我們寫css用的css pixels。所以通過F12工具微調(diào),視覺上大致沒問題就可以了。

當(dāng)把開發(fā)好的頁面用手機(jī)預(yù)覽的時候你會發(fā)現(xiàn)圖片跟背景圖錯位了,因為背景圖的上下邊緣有裁剪,按照裁剪之后的高度來定位浮動圖片的話,圖片肯定會全部往下錯位。怎么辦?

解決方案:我們給浮動元素們包裹一個relative屬性的父元素,比如叫div.editarea,Emmet表示為div.page>div.editarea>浮動元素們。注意,背景圖是設(shè)在div.page身上的,不要給.editarea設(shè)背景圖。然后給這個元素再加一個class叫.editarea-offset,讓.editarea-offsettop等于calc((100% - 520px) / 2),它是一個負(fù)值,就是被裁減的厚度值,這樣浮動元素們的向下的錯位就被向上拉動,也就是修正了。

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

什么時候不需要加這個.editarea-offset修正呢?比如,現(xiàn)在有個浮動元素,它內(nèi)部不含圖片,或者它雖然含圖片,但不要跟背景圖對位,現(xiàn)在我要求它必須占據(jù)100%視口高度,且不可溢出,這種情況下就不需要加.editarea-offset

這種情況一般是出現(xiàn)在只包含純文字且文字很多的元素。這種情況下我們當(dāng)然希望它盡可能占據(jù)最大面積,顯示最多的文字,比如我打算在頁面頂部放一個大標(biāo)題,下面放列表,項目有很多,局部滾動。就如:

<div class="xxlist">
<h1>大標(biāo)題</h1>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
...
</ul>
</div>

現(xiàn)在我想讓.xxlist的高度盡可能高,達(dá)到100%高度,然后ul也盡量高,局部內(nèi)容滾動,所以不能寫死ul的height值,這時候height的正確姿勢是:

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

也就是說,h1的容器高度是32px的話,ul的高度就calc計算一下,就好了。

浮動圖片寬高問題

浮動元素的圖片都是按照720x1170畫布的前提下設(shè)計的,所以需要先算出相對于320x520的css像素寬高,然后才能寫入代碼里。這個運算讓sass自己去算就行了。也就是:

  • 先看設(shè)計師發(fā)過來的圖片的寬高,先如實抄到代碼里。比如設(shè)計師給你的圖就是23px的寬度,就抄23px。這個23px是設(shè)備像素。下一步我們把設(shè)備像素?fù)Q算成css像素。
  • 比如你的width: 123px這樣子的代碼,應(yīng)該寫成width: round(123px * 320 / 720),也就是寫成round(123px * 4 / 9)。sass編譯的時候會自動幫你計算。高度值也是一樣處理。

浮動文字的字號和行高問題

字體跟圖片的處理是一樣的道理,字號單位并不用什么高深的rem,直接用px即可。當(dāng)然,用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元素設(shè)寬度,因為inline-block就可以保證寬度自適應(yīng),而且加動畫之后,比如加中心放大的動畫,可以確保中心點正確。

本文只為介紹適配,適配大致就是這些內(nèi)容,至于怎么真正做出一個翻頁H5,那就是本文之外的內(nèi)容了。以后會寫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容