Introduction
隨著 iPhone X 的 release, 越來越多的硬體廠商, 也紛紛跟 Apple 致敬, 推出了玲琅滿目的全屏裝置. 如何有效利用當前 viewport, 讓 web page 能做最佳的呈現, 其實一直都是每位 frontend engineer 應盡的本分與義務.
為了讓 developers 有個遵循的依歸, 所以 Apple 官方明確的定義出相關的 design guideline, 文件中明確指出該怎麼設定, 讓 developers 在有效使用 viewport 範圍的當下亦不會被硬體配置所阻擋 (ex: Sensor Housing or front camera)
文件中帶來了兩個新穎的設定, 分別是 meta[name=viewport] 以及 CSS variable env() 的 support.
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,viewport-fit=cover"><meta name="theme-color" content="#000">
<meta name="apple-mobile-web-app-title" content="Your site title">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="apple-touch-icon" href="your_site_icon.png">
<link rel="apple-touch-startup-image" href="your_site_startup_image.png">...
...
...<style>
.post {
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
</style>
以上便是 iOS standalone mode 的幾個基本設定與用法, 透過這些設定, developers 便可以有效地來使用 viewport. (由於系統制約的關係, iOS 並不允許 developers 使用上方的系統區塊, 頂多只能改改顏色, apple-mobile-web-app-status-bar-style)
User 在 browse web page 的當下, 完成 Add to home screen 的動作後, 便可以如下圖, 完整的來使用 viewport.
以上便是 Apple 針對全屏裝置所帶來的嶄新觀念與設定, 那麼… Android 系統又是怎麼看待這件事情呢 ?!
要同時 support 不同的 OS 其實一直都是 developers 揮之不去的夢魘, iOS ready 了, 不代表 Android 就一定 ok, 更不用說 Android device 的開發商更是多不勝數, 想來就是一個不可能的挑戰.
幸好 Android 在這件事情的態度和 Apple 是一致的, 更棒的是…上面講到的 meta[name=viewport] 以及 CSS variable env(), Android 通通都有支援, 也就是說 developers 同樣的寫法可以直接使用在 iOS 以及 Android 上, 不需要額外的 dirty works.
Turn on fullscreen mode at Android
Progressive Web APP 這兩年來不斷地發酵, 隨著 Google TWA 的 announce, 又將其討論熱度往上提升一個層次. 為了要提供類 APP 的 fullscreen 呈現, 因此必須要遵守上段所述的 guideline.
Android 的設定和 iOS 會略有不同, iOS 主要是認 meta 上面的三個設定
<meta name="apple-mobile-web-app-title" content="Your site title">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
Android 則主要看 manifest 裡面的內容, 也就是說要 turn on fullscreen mode 的起手式, 便是提供一份完整的 manifest 檔案, 我們來看一下我個人 Side-Projetc: Yahoo 奇摩超級商城的 manifest 設定
{
"dir": "ltr",
"lang": "zh-Hant-TW",
"short_name": "超級商城",
"name": "Yahoo奇摩超級商城",
"start_url": "https://blog.lalacube.com/mei/yahoo_mall_fp_amp.php?launcher=true",
"display": "fullscreen",
"background_color": "#00b3ff",
"theme_color": "#00b3ff",
"description": "Yahoo 雅虎超級商城, 擁有超過百萬商品評價推薦的 NO. 1 購物第一站。流行名店,運動休閒,生活量販,生鮮食品,寵物用品,3C電器,送禮小物,文青用品 通通一網打盡你的購物慾望。每天都有最優惠的折價券/ 超贈點回饋讓你買的划算有保障!",
"orientation": "portrait",
"icons": [
{
"src": "https://s.yimg.com/ma/auc/app/ymall-r-192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "https://s.yimg.com/ma/auc/app/ymall-r-256x256.png",
"type": "image/png",
"sizes": "256x256"
},
{
"src": "https://s.yimg.com/ma/auc/app/ymall-r-384x38x.png",
"type": "image/png",
"sizes": "384x384"
},
{
"src": "https://s.yimg.com/ma/auc/app/ymall-r-512x512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"related_applications": [
{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=com.yahoo.mobile.client.android.ecstore"
},
{
"platform": "itunes",
"url": "https://itunes.apple.com/tw/app/yahoo%E5%A5%87%E6%91%A9%E8%B6%85%E7%B4%9A%E5%95%86%E5%9F%8E/id778296354?mt=8"
}
]
}
manifest 裡面可以有很多細部設定, 在這裡我們特別注意到 display 以及 orientation 這兩個 key, 因為他們在 PWA 中起了至關重要的設定
- display: 透過該值決定 PWA 啟動後的主要呈現, 因為我們希望他是 fullscreen mode, 所以自然就是將之設定為 fullscreen
- orientation: 透過該值決定 PWA 主要的 viewport 模式, 可以為
portrait
orlandscape
,一但設定後, 則 orientation 便會被鎖住, 不管 device 怎麼轉, 內容物都會維持當初設定的 value.
關於 manifest 的其他設定有興趣的朋友, 也可以點擊下方連結進行一覽
完成上述設定後, developer 便完成了 fullscreen mode 的 PWA, 當我們開心的點擊已經存在 home screen 上的 icon 後, 便可以觀察到實際地呈現了
疑?! 明明都照著上面的步驟走了, 為什麼還會出現這樣的狀況呢 ?! 相信不少人心中存著這樣的疑惑.
和 iOS 相比, 對於 fullscreen 的定義上顯見 Android 大方多了, 它真的就是整個區塊通通給你使用, 不會有所謂的系統保留區塊, 也就是說 … developers 本身也需要注意到上方區塊會不會被硬體配置所阻擋.
那麼該如何避免這樣的情況發生呢?! 經實驗一下, Android Chrome 不僅有支援 env(safe-area-inset-left)、env(safe-area-inset-right) 以及 env(safe-area-inset-bottom).
甚至還有支援 Apple 文件上所沒有撰寫到的 env(safe-area-inset-top)
也就是說…只要 developers 有特別處理這一部分, 便可以輕輕鬆鬆避開頁面被硬體配置所阻擋的窘境, 以下為我個人簡單的處理, 提供給大家參考
<style>#hd {
...
padding-top: var(--sait, 0);
}@supports (bottom:env(safe-area-inset-top)) {
:root: {
--sait: env(safe-area-inset-top, 0px);
}
@media screen and (orientation:landscape) {
:root {
--sait: 0;
}
}
}</style>
簡單描述一下上面的 CSS 做了什麼 ?
- #hd 為假定的 header, 這時候先設定 padding-top 為 sait, 如果變數 sait 不存在, 則讓她 fallback 為 0
- 透過 supports 來偵測當前環境是否有支援 env(safe-area-inset-top), 如果有支援, 便設定 sait 的 value 為 env(safe-area-inset-top), 為了避免 error occur, 所以多上一層保險, 如果拿不到 sait 就讓她 fallback 為 0px
- 最後再上一層保險, 如果 device 當前的 viewport 為 landscape 模式, 那麼就把該值取消, 因為我們不希望 landscape 下, header 有那個 padding-top 存在
把上面的 CSS 加入後, 再重新點擊方才的 PWA icon 後,
終於… env(safe-area-inset-top) 正常的發揮了它的作用, 而我們也成功地避開頁面被硬體配置所阻擋的窘境了
Summary
以上, 便是 Android Chrome fullscreen mode 下所需要特別注意的事項, 最後再來幫大家做個總結
- 提供完整的 manifest 檔案, 尤其注意 display 以及 orientation 這兩個的 value 設定. 若要使用 fullscreen, 只要 display: fullscreen 即可.
- meta[name=viewport] 以及 CSS variable env() 的設定不能少, 遵循 iOS design guideline 的定義
- 在 Android 下, fullscreen mode 實際上是可以支配到 top 的系統區塊, 所以可以透過 env(safe-area-inset-top) 的設置, 來避開被遮蔽的窘境