問題重述
本文討論的適配不是指傳統的 @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 的副作用
- input 游標變粗
scale 對整個頁面縮放會導致 iOS 下頁面裡的 Input 和 Textarea 等輸入框的游標變粗,超難看,安卓好像不會
解決方案:放棄 scale 適配,改用其他方案
- z-index
scale 可能對 z-index 的效果有影響,不確定,因為 z-index, fixed, 虛擬鍵盤這幾個因素會相互影響,引發極難解決的其他問題
解決方案:float 會讓 z 無效,position 的預設值也會讓 z 無效,更多資訊請查看 div 層調整 zindex 屬性無效原因分析及解決方法
- 水平捲軸
寬螢幕下可能出現消不掉的水平捲軸,無論怎麼設置 overflow 都無效
解決方案:不要給 body 設置 scale,給 wrapper 設置。如果本來就是這樣就反過來做(給 body 設置 scale),還不行就考慮剝離其他因素,z-index, fixed, input 等等都可能與這個有關
- fixed 佈局失效
scale 之後 fixed 佈局會失效,fixed 部分會跟著頁面捲動,虛擬鍵盤彈出也會引發這個問題
解決方案:改用 absolute + JS 輔助定位,如果是複雜的 fixed 佈局,比如 fixed 層上有 input,還是放棄 scale 適配吧,bug 會沒完沒了的
- 虛擬鍵盤破壞佈局
彈出虛擬鍵盤後 fixed 佈局就失效了,目前沒得解
3. 結論
可以放心去用 scale 縮放適配「簡單」頁面,「簡單」的定義是:
-
沒有 input,textarea 等輸入框,保證不會彈出虛擬鍵盤
-
沒有複雜的 z-index 層級
-
沒有 fixed 部分
如果頁面不滿足上面的任意一條,建議不要用 scale 來縮放適配,會被 bug 轟炸的
P.S. zoom 縮放適配筆者用得不多,至於用 scale 還是 zoom,有以下原則:
-
大前提:行動頁面不要求支援 IE 的話可以用 scale,否則乖乖用 zoom 吧,如果相容 Firefox 很重要的話,還得添上 hack
-
圖片縮放用 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,因為:
- 難算
當前元素的 fz 值來自所有祖輩元素
- 冗餘標籤
見上面的注意部分
- 不夠靈活,難以維護
當前元素的 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:不給了,看案例吧
案例
-
高德地圖_全明星導航語音活動:字型沒有做縮放處理,要求不高
-
京東行動版:字型沒有做縮放處理,但內容以圖片為主,影響不大
四. 行動頁面適配方案總結
-
首選 scale/zoom 方案,前提是頁面簡單(簡單的定義見前文)
-
不行就考慮 rem/em 方案,注意相容性(rem[IE8-])
-
實在不行就用 img 方案,要求不高的話可以不管字型,否則,你悲劇了
暫無評論,快來發表你的看法吧