H5 IphoneX 適配簡述

? IphoneX 的適配,關(guān)鍵在于怎么讓頁面適應(yīng) “齊劉?!?/strong>、底部操作區(qū)域以及大圓角問題。

? IphoneX 相對于其他手機(jī),不同之處在于設(shè)備雖同樣都是一個屏幕,但其實被分為了好幾個模塊,具體見下圖:


? 我們正常的一個網(wǎng)頁,搬到X上來,效果是 內(nèi)容只顯示在 Safe Area 安全區(qū)域,非安全區(qū)域部分沒有網(wǎng)內(nèi)容,也就是說頭部和底部會出現(xiàn)白塊,怎么處理?

解決辦法

? 1. 給body加一個 background-color

? 為什么要加 background-color?有什么用? 注意到我們剛說到的 頭部和底部會出現(xiàn)白塊,其實說是白色其實并不準(zhǔn)確,因為這個顏色其實來自于 body 的背景色。另外,我們上拉或下拉內(nèi)容時會顯示網(wǎng)頁下方的內(nèi)容及顏色,其實也是body的背景顏色。所以如果你想修改這兩個效果,就可以設(shè)置一下 body 的背景色。

? 2. 添加 viewport-fit = cover 的 <meta> 標(biāo)簽

? 這一步極為關(guān)鍵。先看一下結(jié)果:
<meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0, width=device-width, viewport-fit=cover" />

? 為什么說極為關(guān)鍵? iphoneX 的主要問題就是除了安全區(qū)域外,其他地方不能顯示網(wǎng)頁內(nèi)容,而它就是為解決這個問題而量身定制的。當(dāng)設(shè)置了以上內(nèi)容后,頭部和底部就能開放給網(wǎng)頁顯示內(nèi)容。
? 但是用了之后你會發(fā)現(xiàn),區(qū)域是開放了,但是內(nèi)容(常為導(dǎo)航欄)卻因為“齊劉?!倍徽趽踝×瞬糠謨?nèi)容,并且,發(fā)現(xiàn)原本設(shè)置的100%的高度并沒有占用全部高度空間,怎么辦?

? 對于頭部的高度和底部的高度,其實是有匹配值的,如下圖:


所以,我們有如下方案處理:

? 1. 修改我們導(dǎo)航欄的高度,為原本高度加上safe-area-inset-top 的高度,也就是44px;具體可以這么寫:
height: calc(navHeight + 44px);,并且重新設(shè)置一下導(dǎo)航欄上文案的位置。

? 2. IOS 11的瀏覽器chromium內(nèi)核提供了以下內(nèi)容,也就是我們上圖標(biāo)注的那幾個值:

  • safe-area-inset-top
  • safe-area-inset-right
  • safe-area-inset-left
  • safe-area-inset-bottom

? 怎么用呢?很簡單:

body {
    padding-top: constant(safe-area-inset-top);   //為導(dǎo)航欄+狀態(tài)欄的高度 88px            
    padding-left: constant(safe-area-inset-left);   //如果未豎屏?xí)r為0                
    padding-right: constant(safe-area-inset-right); //如果未豎屏?xí)r為0                
    padding-bottom: constant(safe-area-inset-bottom);//為底下圓弧的高度 34px       
}

? 也許你沒見過 constant這個東西,我以前也沒見過,它也是專為iphoneX而設(shè)計的值,注意只有當(dāng)你的 <meta> 標(biāo)簽加上了 viewport-fit=cover 之后,該值才能生效。當(dāng)然,在android手機(jī)上,是不會被識別的。


2018-2-8更新】漏了解釋constant(safe-area-inset-top) 是干嘛的了
? 設(shè)置了 viewport-fit=cover 之后,ios11手機(jī)的整個屏幕都變成了可用的“安全區(qū)域”,包括狀態(tài)欄,但是狀態(tài)欄其實并不是我們想要使用的區(qū)域,不僅如此,還會影響我們頁面的展示。如iphoneX手機(jī)的“齊劉?!睍踝?nèi)容,6/7/8[plus]的狀態(tài)欄(顯示時間和電池信息等)也會擋住頁面內(nèi)容。這也就是說,這塊區(qū)域的內(nèi)容屬于不可使用區(qū)域,但是cover又給我們打開了,所以我們需要 padding 掉。但是不同手機(jī)如X和8的狀態(tài)欄高度不一致,我們應(yīng)該設(shè)置多少呢?ios提供的constant(safe-area-inset-top)能幫我們識別出相應(yīng)手機(jī)的狀態(tài)欄高度,因此,就有了以上用法。


3. 只為 IphoneX 生效

? 注意了,我們做的這個適配是只為 IphoneX 生效的,并不能影響到其他手機(jī),所以我們要做響應(yīng)式布局,即,使用媒體查詢,如下:

// 注意這里采用的是690px(safe area高度),不是812px;
@media only screen and (width: 375px) and (height: 690px){
    body {
        height: 100vh;
    }
}

? 有資料說上面這么用是ok的,然而我用著卻沒啥效果,于是我放寬了點條件,做了修改如下:

@media only screen and (width: 375px) and (min-height: 690px){
    body {
       height: 100vh;
    }
}

? 區(qū)別在于我是識別寬度為375px,高度大于690px 的設(shè)備即為 IphoneX。當(dāng)然,目前只有X 這款設(shè)備符合該條件。

4. 網(wǎng)頁高度變化

? 先強(qiáng)調(diào)一下,這部分不太確定,我自己遇到了,提出來說明一下:
2018-2-8更新】已確定,確實會發(fā)生變化。

? 設(shè)置了 viewport-fit 之后,會發(fā)現(xiàn)原本設(shè)置的100% 的高度不符合預(yù)期,只占用了部分屏幕空間(因為狀態(tài)欄高度也被包入了),沒關(guān)系,我們只需要作如下修改:

@media only screen and (width: 375px) and (min-height: 690px) {
    body {
        height: 100vh;
    }
}

? vh 是檢查 viewport 即視口的高度,1vh = 1% 視口高度,是個絕對單位。設(shè)置100vh的意思就是占滿全屏高度

5. 導(dǎo)航欄吸頂,任務(wù)欄吸底

? 頁面內(nèi)容可以拉動,如果導(dǎo)航欄也隨著滑動,效果很丑,這就需要我們實現(xiàn)導(dǎo)航欄吸頂效果。具體實現(xiàn)使用position:fixed,大家都會就不啰嗦了,展示一個我的案例:

@media only screen and (width: 375px) and (min-height: 690px){
  div {
    position: fixed;
    display: block;
    z-index: 300;
  }
  .bg {
    height: calc(3.5rem + 44px);
  }
  p {
    margin-top: 44px;
  }
}

任務(wù)欄同理。
?

后語

? 本文只是簡單的描述一下如何處理IphoneX的適配問題的具體步驟,如果還想更深入的了解原理,歡迎大家到評論區(qū)交流。

最后編輯于
?著作權(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ù)。

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