1. 程式人生 > >iPhone X Web前端頁面適配(處理可愛的劉海)

iPhone X Web前端頁面適配(處理可愛的劉海)

一、兩個概念

iPhone X和IOS 11的釋出,不在許多技術方面造成了一定的衝擊,前端也不可以避免地也受到影響,因為iPhone X劉海的影響,在編寫前端頁面的時候要做一些處理,下面先提出一些新的概念。
  1. 安全區域

    因為劉海的關係,所有的展示都會放在一個叫做safe-area的區域,如下圖(1-1),主要是為了防止顯示的內容被劉海感測器(house sensor),圓角邊框(rounded corners)所遮擋,這樣對使用者來說是不友好的,但是如果全部內容被放置在預設的安全區域,顯示的內容就會被壓縮,這個時候需要做一些處理,既然頁面能夠正常顯示,又能夠不被安全區域遮擋。

  2. CSS3新特性viewport-fit

    在w3c.org官方給出的關於圓形展示(Round display)的標準中, 提到了viewport-fit這一屬性,這個屬性表明了對於某些螢幕並不是矩形形狀的裝置的時候瀏覽器該如果進行顯示。傳送門:viewport-fit官方參考文件

  3. CSS3新特性env以及var預定義變數。

    在定義以後viewport-fix以後, 瀏覽器會自動生成四個padding變數,即用來將頁面向內擠壓到可以正常顯示的位置。這個時候需要用到env或者constant來將變數轉換成CSS屬性值並且賦值給屬性。ps:env好像還在開發中,好像只支援IOS 11.2及以上。目前比較穩妥的方法就是constant和env一起使用。傳送門:

    var預定義變數官方參考文件

安全區域Safe_Area說明圖

圖1-1 安全區域(Safe Area)

二、環境要求

軟體環境要求: 能跑xcode 9.1的機器一臺(我用的Mac mini,主要是用來開啟iPhone X模擬器,窮~~~)
            一個IDE(sublime或者vscode隨意)
            一個本地除錯伺服器(用npm安裝一個http-server就行) 
            當然還有最重要的,就是你~~~~

三、開始動手

  1. 在meta中新增viewport-fit=cover(告訴瀏覽器要講整個頁面渲染到瀏覽器中,不管裝置是圓角與否,這個時候會造成頁面的元素被圓角遮擋),如下圖3-1。

邊緣元素被遮擋

圖3-1 邊緣元素被遮擋

  
2. 為了處理這些顯示的問題,我們需要使用到env,constant還有預定義變數safe-area-inset-top,safe-area-inset-right, safe-area-inset-bottom, safe-area-inset-left。全部使用的這些方法或者變數都是在Safari中全部定義好的,我們就正常使用就行。但是別忘記了還要做一個向下相容。

下面附上完整的程式碼以及一些測試圖。

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
    <title>iphone X 螢幕以及其他iphone螢幕適配</title>
    <style>
    /* 一、樣式基本初始化 */
    * {
        margin: 0;
        padding: 0;
    }

    html,
    body {
        width: 100%;
        box-sizing: border-box;
        position: relative;
        height: 1000px;
        background-color: #ccc9ca;
    }

    ul,
    li {
        list-style: none;
        text-align: center;
    }

   /* 導航欄因為是基於螢幕定位,所以padding要進行單獨的計算。env在IOS 11.2中新增的,constant在IOS 11.2 已經被廢棄,但是我們要做相容,所以都要用上。 */
    header {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        display: block;
        box-sizing: border-box;
        /* 因為header導航欄是基於螢幕進行定位,所以要做單獨的padding擠壓處理 */
        padding-right: constant(safe-area-inset-right);
        padding-left: constant(safe-area-inset-left);
        padding-right: env(safe-area-inset-right);
        padding-left: env(safe-area-inset-left);
        overflow: scroll;
        background-color:#2889e8;
    }
    header ul {
        display: block;
        width: 200%;
        background-color:#2889e8;
        box-sizing: border-box;
        line-height: 32px;
        height: 32px;
        padding: 0 10px;
    }
    header ul li {
        float: left;
        padding: 0px 8px;
        color: #666;
        font-weight: 500;
    }
    header ul:after {
        display: table;
        height: 0;
        clear: both;
        height: 0;
        content: "";
    }
    .show {
        margin-top: 36px;
        width: 100%;
        box-sizing: border-box;
        padding: 0px 10px 10px;
    }
    .active {
        color: #2889e8;
        background-color: #ffffff;
    }


    .show li{
        padding: 10px 0;
        background-color: #fff;
        border-radius: 4px;
        margin-bottom: 5px;
    }
    /* body 在橫屏底下和豎屏底下一定要做好定位,不然*/
    /* 豎屏底下的查詢 */
    @media screen and (orientation: portrait) {
        body {
            /* 防止頁面被劉海遮住 */
            padding-top: constant(safe-area-inset-top);
        }
    }
    /* 橫屏底下的查詢 */
    @media screen and (orientation: landscape) {
        body {
            /* IOS 11支援*/
            padding-right: constant(safe-area-inset-right);
            padding-left: constant(safe-area-inset-left);
            /*IOS 11.2版本版本支援*/
            padding-right: env(safe-area-inset-right);
            padding-left: env(safe-area-inset-left);
        }
    }

    </style>
</head>

<body>
    <header style="">
        <ul style="">
            <li class="active">時事</li>
            <li>社會</li>
            <li>熱點</li>
            <li>時事</li>
            <li>社會</li>
            <li>熱點</li>
            <li>時事</li>
            <li>社會</li>
            <li>熱點</li>
        </ul>
    </header>
    <div class="show">
        <ul>
            <li>1 我是列表項</li>
            <li>2 我是列表項</li>
            <li>3 我是列表項</li>
            <li>4 我是列表項</li>
            <li>5 我是列表項</li>
        </ul>
    </div>
    <div class="show">
        <ul>
            <li>1 我是列表項</li>
            <li>2 我是列表項</li>
            <li>3 我是列表項</li>
            <li>4 我是列表項</li>
            <li>5 我是列表項</li>
        </ul>
    </div>
</body>

四、一些測試圖

1. iPhone X豎屏(圖 4-1)以及橫屏( 圖 4-2 )顯示:

iPhone X豎屏顯示


圖 4-1 iPhone X豎屏顯示

  
iPhone X橫屏顯示


圖 4-2 iPhone X橫屏顯示

          

2. iPhone 8 豎屏( 圖 4-3 ) 以及橫屏( 圖 4-4 )顯示:

iPhone 8 豎屏顯示


圖 4-3 iPhone 8豎屏顯示

iPhone 8 橫屏顯示


圖 4-4 iPhone 8橫屏顯示

    

3. iPhone 6 豎屏( 圖 4-5 ) 以及橫屏( 圖 4-6 )顯示:

iPhone 6豎屏顯示


圖 4-5 iPhone 6豎屏顯示

iPhone 6橫屏顯示


圖 4-6 iPhone 6橫屏顯示

五、總結以及提供一些參考資料:

  1. 總結:個人認為iPhone X雖然有了可愛的劉海,可能看起來會很難處理,但是實際上官方提供的方法還是相對簡單的,關鍵還是要看公司的業務邏輯怎麼樣。如果上面我有說的不對的,敬請各位給我提提意見,謝謝大家,共同進步。