滿版網頁在手機上的呈現 ‒ 淺談 Web app 的麻煩事
前言
Web app 顧名思義就是將服務全部做在網頁上,讓使用者不論用電腦或是手機瀏覽器開啟網站,都能完整使用我們想提供的服務,不需事先安裝或定期更新,只需要一個網址。而 Native app 則是我們熟知的必須從 app store 下載的軟體,又因為 ios / android 各有其原生語言:swift / obj C / java,其最大的缺點就是開發成本較高,一般工程師也大多只專精於一種語言,對於公司來說,要開發一款 native app 很可能要同時請好幾位工程師。然而,Web app 最極限可以只請一位工程師 (汗) ,即可做出電腦/手機都通用的服務介面,多好用阿~~
當然,Web app 及 Native app 各自都有好壞,並不表示 Web app 就能全面取代 Native app,這並非本次主題就不細談了。總之,在這樣的模式下,就誕生出許多「想在瀏覽器上做到與 Native app 一模一樣體驗的想法」,比如:小遊戲做在網頁上、滿版的操作介面等等。
網頁滿版?100vh ?
是,css 可以將元件的高度設為 100vh,也就是 100% view height 的意思,但請看圖。
100vh 其實是包含了底部工具列的高度,但往往希望做到滿版畫面需求的案子,大多都是希望
- 隱藏上下工具列,做到如 Native app 一樣全螢幕顯示。
- 可視範圍內不可捲動、或被遮擋到任何元素。
那工具列能直接隱藏嗎?
答案:不行。
手機瀏覽器預設的行為,我們無法從程式內去控制。
不過在 ios 7.1 時,safari 還有提供 minimal-ui 的 meta tag 可以在載入網頁時直接縮小工具列,但後來被拿掉了。
可視範圍內的滿版?
在這之前可以先了解一下 safari 在手機上的行為是如何?
safari 會在網頁最外層套上一層類似 overflow 的 view,當網頁的高度超過 viewport 時,使用者只要向下滑動頁面,便會慢慢地將上方導覽列縮小,同時將下方工具列隱藏。即便我們網頁的高度並沒有超過可視範圍,它仍然會有捲動的效果,如下圖。
剛好找到 Yahoo 字典的搜尋頁就是做滿版網頁,元件都被放置在導覽列&工具列之間,卻仍然有捲動效果(scroll bounce),只是上下捲動後會被自動彈回來,這是 safari 套給它的效果,目前沒找到任何方式能將其 disabled。同時也可以觀察到,不論如何上下捲動,工具列都不會被隱藏(因為高度並沒有超過 viewport)。
沒辦法…與工具列共處吧!
因為不可能隱藏工具列,那麼只好與它和平共處,這也是個人認為 Web app 很大的壞處之一。如果手機不夠大,如:iphone SE (320x568),又必須被上下工具列削減高度,剩下的畫面大約只剩 400 多px,能放的東西寥寥無幾。
至於如何將畫面限定在手機的工具列之間(可視範圍內),又可以在電腦版上正常滿版,我們可以用 innerHeight 來解決:
let height = window.innerHeight;window.addEventListener('resize', () => {
height = window.innerHeight;
});
只要讓網頁外層的 view 都是吃 window.innerHeight,基本上就沒什麼問題了,呈現起來就會如上方 Yahoo 字典的樣子。(好像很容易,但我找很久阿QQ)不過就如前面所看到的,無法避免 scroll bounce 的問題,當這個畫面中塞滿了資訊、列表、及各種操作,此時客戶又希望能夠擁有與 Native app 一樣的使用體驗…
嗯…先讓我冷靜冷靜…
其他解決方式
其實直接 google 「safari 100vh」會發現很多人也碰過同樣的問題,然而 safari 並沒有將這行為視為一個 bug。 It’s a feature !!
網路上很多解決方式都是較舊的,也衍生出了一些創意的做法,這邊整理幾個我覺得有用的方式:
這個主題應該有很多種解法,我也並沒有全部都嘗試,所以如果您有更好的方式也歡迎分享給我~~