一。問題背景
這個需求有點奇怪,移動支持的最佳方案是專門建一個移動站,服務端做 UA 檢測,返回對應的內容
P.S. 關於移動適配方案的更多信息,請查看 [CSS 進階篇 二。如何支持移動瀏覽器](/articles/css 進階篇/#articleHeader2)
場景:PC 站已經建好,且不打算改變 HTML 結構,mobile first 原則不適用
P.S. 其實場景是 CSS 規範翻譯完畢,估計自己以後用手機看得多,所以想通過媒體查詢適配手機顯示。只針對移動設備調整佈局,媒體查詢匹配目標是移動設備(這裡特指手機,且不管橫屏豎屏)
二。可選方案
###1.breakpoints
最常見的方式,通過屏幕寬度(用CSS 像素描述的寬度)來區分各種設備,如下:
@media (min-width:320px) { /* smartphones, portrait iPhone, portrait 480x320 phones (Android) */ }
@media (min-width:480px) { /* smartphones, Android phones, landscape iPhone */ }
@media (min-width:600px) { /* portrait tablets, portrait iPad, e-readers (Nook/Kindle), landscape 800x480 phones (Android) */ }
@media (min-width:801px) { /* tablet, landscape iPad, lo-res laptops ands desktops */ }
@media (min-width:1025px) { /* big landscape tablets, laptops, and desktops */ }
@media (min-width:1281px) { /* hi-res laptops and desktops */ }
/* 另外 */
min-width: 480px: Will target mobile devices in landscape mode and up
以上內容來自 stackwoverflow 2011 年的答案
強調 2011 年是為了引發思考:當年的手機屏幕分辨率小,也沒有 Retina 屏幕這種東西。那麼,現在這樣的媒體查詢規則還有效嗎?
換句話說,為什麼 max-width: 480px 能匹配 1080x1920px 的大屏手機?
關鍵在於這兩個 px不是同一個東西,前者是 CSS 像素,後者是物理像素。而包括 iPhone6p 以及巨屏三星在內的所有手機,CSS 像素寬度都在 320px 到 480px 之間,當然,使用這些查詢規則的前提是設置 viewport meta:
<meta name="viewport" content="width=device-width"/>
把佈局視口的寬度設置為 CSS 像素寬度,所以不用擔心超高分辨率的戰鬥機,至於 Retina 屏幕,壓根和我們的目標(區分移動設備)沒關係。關於三種視口和 Retina 屏幕的詳細解釋,請查看 [完全理解 px,dpr,dpi,dip](/articles/完全理解 px-dpr-dpi-dip/)
P.S.Moto 360 Watch 的 CSS 像素寬度為 218px 到 281px,總之,手錶不會超過 320px,他們不會故意製造混亂
###2.touch 事件
一種取巧的方法,如下:
<script type="text/javascript">
//detect if browser supports touch
var is_touch_device = 'ontouchstart' in document.documentElement;
if(is_touch_device){
$('body').addClass('touchDevice');
}else{
$('body').addClass('notTouch');
};
</script>
假設 移動設備 === 支持 touch 事件,可能會存在兼容性問題,但不會很嚴重(比如 IE 不要也罷)
###3. 設備特性
根據屏幕的寬度以及 DPR 區分各個設備,比如 iPhone6:
/* Portrait and Landscape */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (-webkit-min-device-pixel-ratio: 2) {
}
/* Portrait */
@media only screen
and (min-device-width: 375px)
and (max-device-width: 667px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
}
更多設備對應的查詢規則請查看 Media Queries for Standard Devices
P.S. 雖然這個方案並不能很好的解決我們的問題,但可以用來錦上添花(針對特定設備做處理,比如給 Retina 屏幕開小灶)
三。結論
採用了方案 1 breakpoints,具體如下:
/* Smartphones (portrait and landscape) ----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 480px) {
/* Styles */
}
以上代碼來自 CSS Media Queries For Mobile Devices
其實,單從結論上看,我們根本不需要尋找其它方案,這種最簡單的方法就是最有效的
但原理牽扯的東西比較多:三個視口,DPR,DPI,CSS 像素,物理像素等等
不明所以的人一定會對高分辨率戰鬥機和 Retina 屏幕心存疑慮,引 別人的回答:
What makes you think media queries won't work?
Apparently, Galaxy S4's CSS pixel ratio is 3.0, therefore, while its physical resolution is 1080x1920, its CSS resolution is still 360x640 - similar to Galaxy S3.
There are also media queries that test for pixel density. They may help you to serve high-res pictures or vector graphics to hi-dpi devices.
http://en.wikipedia.org/wiki/List\_of\_displays\_by\_pixel\_density#Samsung
Plus, take a look at this article:
Awesome database of screen specifications
P.S. 英文看著更容易讓人信服,對吧,為什麼呢?
四。注意事項
對 CSS 規範使用媒體查詢時發現:
微信內置瀏覽器不支持
@media (min-device-width : 320px)
需要修改 html meta
width=device-width 再用
@media (min-width:480px)
很隱晦的問題,所以千萬不要使用 min-device-width,看似省事
參考資料
都鏈接在上文裡了,另外,強烈建議看看 [完全理解 px,dpr,dpi,dip](/articles/完全理解 px-dpr-dpi-dip/),穩賺不賠
暫無評論,快來發表你的看法吧