安全區域指的是一個可視視窗範圍,處于安全區域的内容不受圓角(corners)、齊劉海(sensor housing)、小黑條(Home Indicator)影響,如下圖藍色區域:

也就是說,我們要做好适配,必須保證頁面可視、可操作區域是在安全區域内。
更詳細說明,參考文檔:Human Interface Guidelines - iPhoneX
iOS11 新增特性,蘋果公司為了适配 iPhoneX 對現有 <code>viewport meta</code> 标簽的一個擴充,用于設定網頁在可視視窗的布局方式,可設定三個值:
contain: 可視視窗完全包含網頁内容(左圖)
cover:網頁内容完全覆寫可視視窗(右圖)
auto:預設值,跟 contain 表現一緻
注意:網頁預設不添加擴充的表現是 viewport-fit=contain,需要适配 iPhoneX 必須設定 viewport-fit=cover,這是适配的關鍵步驟。
更詳細說明,參考文檔:viewport-fit-descriptor
iOS11 新增特性,Webkit 的一個 CSS 函數,用于設定安全區域與邊界的距離,有四個預定義的變量:
safe-area-inset-left:安全區域距離左邊邊界距離
safe-area-inset-right:安全區域距離右邊邊界距離
safe-area-inset-top:安全區域距離頂部邊界距離
safe-area-inset-bottom:安全區域距離底部邊界距離
這裡我們隻需要關注 safe-area-inset-bottom 這個變量,因為它對應的就是小黑條的高度(橫豎屏時值不一樣)。
注意:當 viewport-fit=contain 時 env() 是不起作用的,必須要配合 viewport-fit=cover 使用。對于不支援env() 的浏覽器,浏覽器将會忽略它。 需要做向後相容,像這樣:
注意:env() 跟 constant() 需要同時存在,而且順序不能換。
更詳細說明,參考文檔:Designing Websites for iPhone X
了解了以上所說的幾個知識點,接下來我們适配的思路就很清晰了。
新增 viweport-fit 屬性,使得頁面内容完全覆寫整個視窗:
前面也有提到過,隻有設定了 viewport-fit=cover,才能使用 env()。
這一步根據實際頁面場景選擇,如果不設定這個值,可能存在小黑條遮擋頁面最底部内容的情況。
類型一:fixed 完全吸底元素(bottom = 0),比如下圖這兩種情況:
可以通過加内邊距 padding 擴充高度:
或者通過計算函數 calc 覆寫原來高度:
注意,這個方案需要吸底條必須是有背景色的,因為擴充的部分背景是跟随外容器的,否則出現镂空情況。
還有一種方案就是,可以通過新增一個新的元素(空的顔色塊,主要用于小黑條高度的占位),然後吸底元素可以不改變高度隻需要調整位置,像這樣:
空的顔色塊:
fixed 非完全吸底元素(bottom ≠ 0),比如 “傳回頂部”、“側邊廣告” 等
像這種隻是位置需要對應向上調整,可以僅通過外邊距 margin 來處理:
或者,你也可以通過計算函數 calc 覆寫原來 bottom 值:
寫到這裡,我們常見的兩種類型的 fixed 元素适配方案已經了解了吧。如果我們隻希望 iPhoneX 才需要新增适配樣式,我們可以配合 @supports 來隔離相容樣式,當然這個處理對頁面展示實際不會有任何影響: