跳到主要內容
黯羽輕揚每天積累一點點

行動頁面適配方案

免費2015-08-20#Front-End#Solution#移动页面适配#机型适配#适配解决方案#em#rem#scale整页缩放#zoom缩放

行動頁面需要相容各種版本的 Android 和 iOS 瀏覽器,適配各種解析度的螢幕是個棘手的問題,本文詳細介紹 2 種常用的頁面適配解決方案,及其優缺點

問題重述

本文討論的適配不是指傳統的 @media 媒體查詢

  • media query 用於區分行動裝置和 PC、Pad,需要針對這些裝置寫 3 套樣式,一般是百分比寬度 + 小螢幕隱藏部分內容

  • 本文討論的適配是希望在不改變頁面佈局/內容的前提下,希望頁面在各個行動裝置上視覺效果大致相同,例如:

我們希望在 iPhone 6 上和 iPhone 4 上效果大致相同,單純 CSS 是不行的,需要 JS 配合佈局才能適應各種各樣的行動裝置,適配行動裝置螢幕有很多難點:

  • 螢幕寬高比不同

有很矮很胖的手機,也有很窄很長的手機

  • DPI 不同

有螢幕特別小,但解析度特別高的螢幕

  • 高清螢幕(Retina)下圖片失真

有把一個像素點掰成幾瓣顯示的螢幕

media query 無助於解決這些問題,本文討論的方案也只能勉強解決(麻煩,或者存在副作用)

一. scale/zoom 縮放整個頁面

1. scale 與 zoom 的區別

  • zoom 縮放,預設以左上角為中心,不能改,不存在覆蓋周圍元素的問題

  • scale 縮放,預設以中心位置為中心,可以改,存在覆蓋周圍元素的問題(擴展出的東西不佔空間)

  • zoom 對子元素縮放,會破壞對齊

  • scale 對子元素縮放,會破壞對齊,用於 inline 元素無效

  • zoom 對父元素縮放,不會影響相對位置

  • scale 對父元素縮放,如果設置以左上角為中心就不會影響相對位置

  • zoom 相容除 Firefox 之外的任何瀏覽器(IE5.5+)

  • scale 相容 IE11+,相容 Firefox

DEMO: scale 和 zoom 的區別

2. scale 的副作用

  1. input 游標變粗

scale 對整個頁面縮放會導致 iOS 下頁面裡的 Input 和 Textarea 等輸入框的游標變粗,超難看,安卓好像不會

解決方案:放棄 scale 適配,改用其他方案

  1. z-index

scale 可能對 z-index 的效果有影響,不確定,因為 z-index, fixed, 虛擬鍵盤這幾個因素會相互影響,引發極難解決的其他問題

解決方案:float 會讓 z 無效,position 的預設值也會讓 z 無效,更多資訊請查看 div 層調整 zindex 屬性無效原因分析及解決方法

  1. 水平捲軸

寬螢幕下可能出現消不掉的水平捲軸,無論怎麼設置 overflow 都無效

解決方案:不要給 body 設置 scale,給 wrapper 設置。如果本來就是這樣就反過來做(給 body 設置 scale),還不行就考慮剝離其他因素,z-index, fixed, input 等等都可能與這個有關

  1. fixed 佈局失效

scale 之後 fixed 佈局會失效,fixed 部分會跟著頁面捲動,虛擬鍵盤彈出也會引發這個問題

解決方案:改用 absolute + JS 輔助定位,如果是複雜的 fixed 佈局,比如 fixed 層上有 input,還是放棄 scale 適配吧,bug 會沒完沒了的

  1. 虛擬鍵盤破壞佈局

彈出虛擬鍵盤後 fixed 佈局就失效了,目前沒得解

3. 結論

可以放心去用 scale 縮放適配「簡單」頁面,「簡單」的定義是:

  1. 沒有 input,textarea 等輸入框,保證不會彈出虛擬鍵盤

  2. 沒有複雜的 z-index 層級

  3. 沒有 fixed 部分

如果頁面不滿足上面的任意一條,建議不要用 scale 來縮放適配,會被 bug 轟炸的

P.S. zoom 縮放適配筆者用得不多,至於用 scale 還是 zoom,有以下原則:

  1. 大前提:行動頁面不要求支援 IE 的話可以用 scale,否則乖乖用 zoom 吧,如果相容 Firefox 很重要的話,還得添上 hack

  2. 圖片縮放用 zoom 和 scale 都行,整頁縮放建議使用 scale

4. 案例

高德地圖_綠色出行活動:scale 縮放整頁適配

5. 框架

白樹的 pageResponse,1.4K 超輕量

二. fontsize + em/rem 相對單位

1. 用 em 縮放

需要給 html(或者 body)設置 font-size: 62.5%;(所謂的 65.5% hack,為了讓 1em=10px 方便計算)。然後把所有長度單位統一成 em,當然,還需要配合 JS 動態改變 html(或者 body)的 font-size

DEMO: 用 em 縮放適配(注意:當前元素的 fz 值會影響 top/left/right/bottom 定位,所以只能再套一層控制 fz,外層用來定位

不建議使用 em,因為:

  1. 難算

當前元素的 fz 值來自所有祖輩元素

  1. 冗餘標籤

見上面的注意部分

  1. 不夠靈活,難以維護

當前元素的 fz 值也會影響所有子元素

2. 用 rem 縮放

最重要的是相容性:[IE8-] 不支援 rem

必須html 設置 font-size: 10px;(10px 還是為了好算)。然後所有長度單位統一用 rem,再配合 JS 設置 html 的 fz 值就好了

DEMO:用 rem 縮放適配

建議儘量使用 rem,rem 不存在繼承值的問題,無需關注祖輩的 fz 值,非常靈活,唯一缺點是相容性問題([IE8-] 不支援)

3. 注意事項

用 em/rem 要注意 Chrome 某些版本不支援 font-size 小於 12(即便設置了 fz 為 10,實際渲染效果也是 12),62.5% hack 會失效,此時 1em/1rem 就不等於 10px 了,而是等於 12px

在高版本的 Chrome 中,設置 -webkit-text-size-adjust: none; 也沒有用,行動端效果未知

4. 案例

淘寶網行動版:單屏 + JS 模擬滑動(很強大的喲~)

5. 用 em/rem 的好處

(一點題外話,和本文內容沒什麼關係)

有的頁面只對文本用 em/rem 做字型單位,其他都用 px,這是為什麼?

因為 px 是絕對單位,而用戶可以設置瀏覽器的預設字型大小,此時如果文本的單位是 px,文本就不會根據用戶的設置放大/縮小,而 em/rem 會

三. img+div 寬度百分比,高度 auto

這是老方法,沒什麼新奇的,缺點是文本不會跟著縮放,有兩種解法:

  • 把文本都切在圖片裡

缺點是頁面載入變慢

  • JS 手動計算改變 fz 值縮放字型(配合 em/rem)

根據螢幕寬高、DPI 等值計算出特定的比例因子,給基礎 fz 乘上來縮放字型,缺點是費勁,而且很難算出合適的比例因子(只能適配部分機型)

DEMO:不給了,看案例吧

案例

四. 行動頁面適配方案總結

  1. 首選 scale/zoom 方案,前提是頁面簡單(簡單的定義見前文)

  2. 不行就考慮 rem/em 方案,注意相容性(rem[IE8-])

  3. 實在不行就用 img 方案,要求不高的話可以不管字型,否則,你悲劇了

參考資料

評論

暫無評論,快來發表你的看法吧

提交評論