移動端適配咱們須要作哪些事情? 一個最佳實踐除了設置 viewport
和 rem
基準值,隨着iPhone手機的不斷升級,咱們不得不正視如下2個問題:css
在切入正題以前,咱們先展開介紹一下viewpoint-fit
,它的做用是用於設置可視區域的尺寸,屬性以下:html
PropName | Description | ||
---|---|---|---|
Name | viewport-fit | ||
For | @viewpoint | ||
Value | auto \ | contaion \ | cover |
Initial | auto | ||
Percentages | N/A | ||
Computed value | as specified |
最初的佈局視窗是經過物理設備的屏幕進行計算,以下圖所示:android
圓形的屏幕上上顯示的頁面的一部分,目前是圓的但視窗是長方形的。所以,根據窗口的大小,頁面的某些部分能夠省略。viewport-fit
能夠經過設置可視區域的大小來控制被省略的區域。ios
auto
:當設置成auto
時,不會影響初始佈局視口,而且整個網頁都是可見的。 UA在視口外部繪製的內容未定義。 它多是畫布的背景顏色,也多是UA認爲合適的任何其餘顏色。contain
:當設置成contain
時,初始佈局視口和可視視口設置爲最大矩形,該矩形內接在設備的顯示中。 UA在視口外部繪製的內容未定義。 它多是畫布的背景顏色,也多是UA認爲合適的任何其餘顏色。cover
:當設置成cover
時,初始佈局視口和可視視口設置爲設備物理屏幕的外接矩形。注意:當設置成contain
時,border-boundary: display
和shape-inside: display
無效。
在非矩形顯示器上設置視口邊界框的大小時,咱們必須考慮如下因素:安全
開發者能夠決定哪一個因素比另外一個更重要。 若是必須保證網頁的任何部分都不被隱藏,則避免剪切比在視口的邊界框和屏幕邊界之間留有間隙更重要。 若是開發者不但願網頁因可讀性而變小,那麼最好將viewport-fit
設置爲cover
並在考慮剪裁部分的狀況下實現頁面。iphone
爲了方便理解,下面是針對 contain
和 cover
的示例代碼和效果圖ide
當使用contain
時,初始視口將應用於顯示的最大內接矩形:佈局
@viewport (viewport-fit: contain) { /* CSS for the rectangular design */ }
當使用cover
時,初始視口應用於顯示的外接矩形:spa
@viewport { viewport-fit: cover; } @media (shape: round){ /* styles for the round design */ } @media (shape: rect){ /* styles for the rectangular design */ }
根據上文所述,爲了安全區域不影響頁面渲染,咱們可使用viewport-fit
等於cover
來來解決:3d
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
ios識別劉海屏比較容易,咱們能夠經過計算屏幕的寬度和高度來快速識別。首先咱們羅列一下iPhone現有機型的屏幕尺寸:
Device | 豎屏尺寸 | 橫屏尺寸 | 縮放比例 |
---|---|---|---|
iPhone XS Max | 1242px * 2688px | 2688px * 1242px | x3 |
iPhone XS | 1125px * 2436px | 2436px * 1125px | x3 |
iPhone XR | 828px * 1792px | 1792px * 828px | x2 |
iPhone X | 1125px * 2436px | 2436px * 1125px | x3 |
iPhone 8 Plus | 1242px * 2208px | 2208px * 1242px | x3 |
iPhone 8 | 750px * 1334px | 1334px * 750px | x2 |
iPhone 7 Plus | 1242px * 2208px | 2208px * 1242px | x3 |
iPhone 7 | 750px * 1334px | 1334px * 750px | x2 |
iPhone 6s Plus | 1242px * 2208px | 2208px * 1242px | x3 |
iPhone 6s | 750px * 1334px | 1334px * 750px | x2 |
iPhone SE | 640px * 1136px | 1136px * 640px | x2 |
其中 iPhone XS Max、iPhone XS、iPhone XR、iPhone X 須要適配劉海屏,而這4類屏幕在真機或模擬器裏表現出來的screen尺寸是有一個共性的:
screen.width === 375 && screen.height === 812 或 screen.width === 414 && screen.height === 896
完整的代碼以下:
function deviceDetection() { const ua = navigator.userAgent let osVersion = '' let device = '' try { if (/android/i.test(ua)) { device = 'android' osVersion = ua.match(/Android\s+([\d.]+)/i)[0].replace('Android ', '') } else if (/ipad|iphone|ipod/i.test(ua)) { device = 'ios' osVersion = ua.match(/OS\s+([\d_]+)/i)[0].replace(/_/g, '.').replace('OS ', '') } } catch (err) { /* istanbul ignore next line */ console.error(err) } return { osVersion, device } } // 判斷是否爲劉海屏 export function isFringe() { const { device } = deviceDetection() const { screen } = global return device === 'ios' && ((screen.width === 375 && screen.height === 812) || (screen.width === 414 && screen.height === 896)) }
此外,Android端雖然劉海屏機型較爲雜多,但咱們習慣容器上會把狀態欄的高度和劉海對齊,從而不影響內容的展現
本文由博客一文多發平臺 OpenWrite 發佈!