兼容iphone x劉海的正確姿式

在 ios 11 中咱們能夠使用 viewport-fit=cover + safe-area-inset-*
那麼是否是 ios11 如下就用不了這些了呢?是的,但你見過 iphone x+ 有 ios 11如下的嗎? 因此咱們能夠愉快的搞下去。css

開始以前咱們先了解什麼是 safe area,簡單的來講就是除了劉海和鬍子之外的區域爲安全區域:ios

 

關於 viewport-fit

viewport-fit 有3個值:
contain: 可視窗口徹底包含網頁內容(左圖)
cover:網頁內容徹底覆蓋可視窗口(右圖)
auto:默認值,跟 contain 表現一致web

 

如何決定 viewport-fit 值?咱們要考慮一些問題:
一、在非矩形顯示器上設置 viewport 邊界時,Viewport邊界框(Viewport Bounding Box)的面積大於顯示區域,致使了剪切區域
二、若是要保證Web頁面的任何部分都沒有隱藏,不想讓Web頁面在可讀性上變得很小,那麼最好將viewport-fit設置爲cover,並在考慮剪切部分時實顯示頁面。
三、還有另外一個考慮是,當咱們設置 viewport-fit:contain,也就是默認的時候時,設置 safe-area-inset-* 等 css 屬性時不起做用的。 點擊這裏瞭解更多關於 viewport-fit瀏覽器

關於 safe-area-inset-*

各類 iphone x 都是不規則形狀,咱們如何控制頁面元素到安全區域呢?apple 把安全區域的位置經過 css 屬性提供給了開發者,它們能夠經過CSS的constant( )函數來完成:安全

constant(safe-area-inset-top):在Viewport頂部的安全區域內設置量(CSS像素)
constant(safe-area-inset-bottom):在Viewport底部的安全區域內設置量(CSS像素)
constant(safe-area-inset-left):在Viewport左邊的安全區域內設置量(CSS像素)
constant(safe-area-inset-right):在Viewport右邊的安全區域內設置量(CSS像素)bash

簡單來講咱們能夠經過 constant( ) 能夠獲取到非安全邊距,再結合 paddingmargin 來控制頁面元素避開非安全區域。 Webkit在iOS11中新增CSS Functions: env( )替代constant( ),文檔中推薦使用env( ),而 constant( ) 從Safari Techology Preview 41 和iOS11.2 Beta開始會被棄用。在不支持env( )的瀏覽器中,會自動忽略這同樣式規則,不影響網頁正常的渲染。爲了達到最大兼容目的,咱們能夠 constant( ) 和 env( ) 同時使用。app

.yourFooterClass {
  padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */
  padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2 */
}
複製代碼

本文爲了簡潔只寫 env( )。iphone

實踐一波

1、設置網頁在可視區域的佈局方式

新增 viweport-fit 屬性,使得頁面內容徹底覆蓋整個窗口:函數

<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover"> 複製代碼

2、讓主體內容控制在安全區域內

假設咱們的底部按鈕高度是50px:佈局

body {
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: 50px;  /* 兼容不支持 env( ) 的設備  */
  padding-bottom: calc(env(safe-area-inset-bottom) + 50px); /* 在 iphone x + 中本句纔會生效 */
  padding-left: env(safe-area-inset-left);
}

有兩個關鍵點:
一、寫在前面的 padding-bottom: 50px 爲了兼容沒有底部鬍子的設備,讓主體內容偏移出底部按鈕的高度,避免按鈕遮擋內容。
二、padding-bottom: calc(env(safe-area-inset-bottom) + 50px); 計算 底部非安全區域距離底部按鈕高度 之和 來作爲 padding-bottom 值,若是設備支持 env,那麼 calc 會計算出一個合法的值,本句的優先級則最高,會覆蓋前面的 padding-bottom: 50px。不然 calc 會計算出一個不合法的值,則本句聲明不會生效。這樣在不支持 env 設備中也能夠達到兼容的目的。

目前到這,在橫屏場景下左側的內容就不會被劉海遮擋住了

3、底部按鈕的處理

首先給底部按鈕一個外層容器 .btn-container ,設置樣式時其中有幾點比較關鍵:
一、設置padding-bottom: env(safe-area-inset-bottom);增長一個 padding 值,讓底部向外擴展一個非安全區域的距離。
二、設置background: #FFF 讓整個 .btn-container 背景爲白色(包括剛新增的 padding-bottom 的區域)這樣就能夠遮擋住了底部內容。
三、設置 box-sizing: content-box; ,由於在一般狀況下 css 在 reset 階段通常都設置了 * {box-sizing: border-box;} 這樣一來設置 padding 就不能向外擴展距離了,因此在這裏咱們要把他改回 content-box

.btn-container {
  box-sizing: content-box;
  height: 50px;
  line-height: 50px;
  color: #fff; position: fixed; bottom: 0; left: 0; right: 0; text-align: center; background: #FFF; padding-bottom: env(safe-area-inset-bottom); } .btn { width: 100%; height: 50px; line-height: 50px; background-color: #00c340; border: none; }
在 safari 中,頁面往上稍滑動一點,出現 safari 的操做欄後,底部按鈕依然會緊貼着操做欄,很是有靈性: 處理起來一切都顯得 簡潔優雅細膩。
轉自IMWeb社區,做者:zzbozheng,原文地址:http://imweb.io/topic/5baa38c279ddc80f36592efb
相關文章
相關標籤/搜索