移動端優雅布局實踐

2021-09-12 23:06:05 字數 2726 閱讀 8894

前言:移動端有非常多的坑,布局首當其衝。
移動端應用有各種複雜的頁面需求,不僅要解決單屏、多屏、固定頭部或底部等多個場景,還要相容ios和android核心,在經歷了專案實戰(手機模式開啟)過後,總結出了一些經驗,在這裡和大家分享一下。

這篇文章是基於 →

next輕量級框架與主流工具的整合

// html高度 = body高度 = 主容器高度

doc.body.style.height = docel.clientheight + 'px';

這樣做也有許多好處:縱向布局十分方便,不管是tab標籤欄、tab標籤頁、頭部固定元素或者底部固定元素實現起來都很簡單;也能很簡單就能實現元素居中對齊、兩端對齊、自動分配空間等;同時也避免了android輸入框引起傳統布局的問題。

不過這裡有個唯一的不好的地方就是相容不了ios的前進返回的操作欄和上下滾動回彈:

這裡補充一下:在ios上如果以正常流布局,內容超過一定高度時,向下滾動會隱藏底部的前進返回欄,向上滾動的時候再顯示出來。當滾動到底部或者頂部時,再繼續拉動頁面,會有乙個回彈的效果。
這兩個問題極大的降低了ios的使用者體驗,又恰逢專案間隔期,有大把的時間,於是被推著到了布局優化上面。

這裡我們在尋找的過程中發現兩個具有代表性的移動端應用:

花瓣網h5

它採用的是設定主容器的position屬性為absolute來脫離文件流的形式。

這兩種布局方式在ios上都使用者體驗極好。但同時也發現他們都存在的一些問題,比如:登入頁面明明不足一屏,卻依然存在滾動;沒有相容iphone x的安全域;彈窗滾動穿透等等。

如果能將這兩種布局和flex進行整合一下,聚合各自的優點,基本上能打造乙個使用者體驗和相容性都令人滿意的移動端應用了。

那麼,如何基於現有的flex布局去整合這兩種布局又成了乙個問題。

在調整之前,我的預期是這樣的:去掉外層高度限制,去掉縱向flex布局(除極少數單屏頁面),將頂部、底部固定和彈窗設定為fixed

考慮到少數單屏頁面需要繼承html視窗的高度,於是採用了主容器脫離文件流的方式。

調整過後dom結構是這樣的:

html > body > div#root > div.main-content(position: absolute)
只需要給main-content加上height: 100%,就可以滿足單屏頁面的需求。

好事多磨!
按照上面的想法進行改造過後又發現了新的問題:脫離文件流過後,切換頁面,html會保持最後滾動的位置

有可能出現滾動條位置被記錄的問題

找了一下發現history有個scrollrestoration的屬性,它有兩個值,乙個是預設值auto還有乙個是manual。如果設定為manual就可以手動設定滾動的位置。

if ('scrollrestoration' in history)
然後在切換路由過後設定滾動的位置為起始位置:

router.events.on('routechangecomplete', () => );
這樣每次切換頁面都是從初始位置開始。

開發遇見的問題,這個demo中沒有出現。這裡有點雞肋,前進後退也不會記錄滾動位置。如果需要前進後退記錄滾動的位置,就不能用這種脫離文件流的形式,需要用body滾動的形式,也就是。
解決滾動穿透這個問題,需要針對有滾動的彈窗和無滾動的彈窗單獨處理。

相容iphone x

在meta標籤後增加viewport-fit=cover

然後留出安全域距離

padding-bottom: 0.49rem; // 底部button的高度

padding-bottom: calc(0.49rem + constant(safe-area-inset-bottom));

padding-bottom: calc(0.49rem + env(safe-area-inset-bottom));

這裡需要注意些padding-bottom的時候需要寫三個,第乙個是為了相容android。

總的來說flex布局還是帶了十分大的便利,尤其是能**居中、適配等一些老大難的問題。

每種布局的方式都有一定的缺陷,到目前為止還沒有一種萬能的方案來解決移動端各種複雜的場景。還是需要根據自己的需求還選擇使用哪種實現方式。

*前面這三種方案各自的缺陷:

縱向flex布局(不建議使用)

body流式平鋪(傳統)

absolute脫離文件流(正在使用)

ios前進後退的操作欄無法隱藏、回彈效果引起卡頓

內部容器無法繼承html視窗高度

路由跳轉可能出現滾動條被記錄

移動端布局

預設以寬度為640px的設計稿為基準頁面,然後通過js獲取當前顯示裝置的尺寸,對應的調整 html 標籤的font size大小,從而實現通過以rem為單位的移動端布局適配。function win,doc function layoutcalc html.style.fontsize rem px...

移動端布局

css畫素與裝置畫素 二者的區別在於前者是抽象的,用於瀏覽器渲染頁面,而後者是裝置的最小物理單位。可參考 a pixel is not a pixel is not a pixel 進行理解。視口 移動端瀏覽器有兩個視口,即可見視口與布局視口,二者的區別在於前者為基於移動裝置螢幕的實際寬度,而後者為...

移動端布局

瀏覽器上 用來顯示網頁的那部分區域了 1 設定 view 有 init scale 頁面的初始縮放值 為數字 width viewport的寬度 height viewport的高度 mininum scale 允許使用者縮放最小值 maxinum scale 允許使用者縮放最大值 user sca...