1. 程式人生 > 實用技巧 >移動端調起軟鍵盤導致 position:fixed 偏移

移動端調起軟鍵盤導致 position:fixed 偏移

1. 問題描述

app內開啟H5頁面,頁面包含input輸入框,點選input調起軟鍵盤,輸入完成點選下方提交按鈕彈出toast時,會出現ttoast跳動的現象,其中:toast採用position: fixed進行固定定位

2. 分析原因

關於position: fixed

首先來看,MDN 中對position: fixed的說明:

不為元素預留空間,而是通過指定元素相對於螢幕視口(viewport)的位置來指定元素位置。元素的位置在螢幕滾動時不會改變。

注意到,position: fixed是相對螢幕視口(viewport)的位置來定位的。 那麼toast跳動是否是因為viewport的改變呢?

關於viewport

MDN 中對viewport的說明:

@viewport 規則讓我們可以對文件的大小進行設定viewport。這個特性主要被用於移動裝置。 按百分比計算尺寸的時候,就是參照的初始視口(viewport)。初始視口指的是任何使用者代理和樣式對它進行修改之前的視口。桌面瀏覽器如果不是全屏模式的話,一般是基於視窗大小。

在移動裝置上(或者桌面瀏覽器的全屏模式),初始視口通常就是應用程式可以使用的螢幕部分。它可能是全屏或者減去由作業系統或者其它應用程式所佔用的部分(例如狀態列)

我們注意到,viewport是會隨著作業系統或者應用程式佔用而變化的,那是不是在調起軟鍵盤的時候,改變了viewport呢

驗證猜想

js提供了Window.innerHeight方法,用來獲取瀏覽器視窗的視口高度。
經過驗證,在調起軟鍵盤時,確實改變了viewport,此時的視口高度是我們看到的可視螢幕高度-鍵盤高度, 所以我們看到的toast跳動是因為viewport的改變而導致。

3. 解決辦法

通過絕對定位position: absolute來替代position: fixed

通常toast是直接插入到body元素下面的(當然可以是別的任何元素),即toast是body元素的直接子元素,因此,可以設定toast相對body元素進行絕對定位。

程式碼如下:


body {
    position: relative;
}
.toast {
   //  固定螢幕中間
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}

東莞vi設計https://www.houdianzi.com/dgvi/ 豌豆資源網站大全https://55wd.com

4. 注意事項

在使用通過絕對定位position: absolute來替代position: fixed的解決方案時,如果top、left設定百分比,就需要注意設定絕對定位元素的offsetParent的height及width值。

因為,絕對定位是相對離它最近的position屬性值不為static的父元素(即offsetParent)來進行定位,並且top、left設定百分比是以offsetParent的height和width來計算的。

比如上述動圖中的例子,可以看到body的內容高度遠遠不到螢幕高度,因此想要實現toast在螢幕居中,就需要為body元素設定合理的高度(通過設定min-height或者height)。

上述例子的完整程式碼:

html{
    height: 100%;  // 設定html為瀏覽器視窗高度(不設100%的話,html 高度就等於body的高度)
}
body {
    position: relative;
    min-height: 600px;  // 設定最小高度
}
.toast {
   //  固定螢幕中間
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}

offsetParent概念補充

The HTMLElement.offsetParent read-only property returns a reference to the object which is the closest (nearest in the containment hierarchy) positioned containing element. If the element is non-positioned, the nearest td, th, table or the body is returned.

5. 總結

針對移動端調起軟鍵盤導致position:fixed偏移的問題,可以通過絕對定位(position: absolute)替代固定定位(position:fixed)來曲線救國。 如果topleft設定百分比,則同時注意設定絕對定位元素的offsetParentheightwidth值。