跳到主要内容

只针对移动设备的媒体查询

PC站已经建好,且不打算改变HTML结构,mobile first原则不适用

免费2016-06-25#CSS#Solution#media query for mobile devices

试读

##一.问题背景

这个需求有点奇怪,移动支持的最佳方案是专门建一个移动站,服务端做UA检测,返回对应的内容

P.S.关于移动适配方案的更多信息,请查看CSS进阶篇 二.如何支持移动浏览器

场景: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像素宽度都在320px480px之间,当然,使用这些查询规则的前提是设置viewport meta:

<meta name="viewport" content="width=device-width"/>

把布局视口的宽度设置为CSS像素宽度,所以不用担心超高分辨率的战斗机,至于Retina屏幕,压根和我们的目标(区分移动设备)没关系。关于三种视口和Retina屏幕的详细解释,请查看完全理解px,dpr,dpi,dip

P.S.Moto 360 Watch的CSS像素宽度为218px281px,总之,手表不会超过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

http://bjango.com/articles/min-device-pixel-ratio/

Plus, take a look at this article:

http://www.html5rocks.com/en/mobile/high-dpi/

Awesome database of screen specifications

http://screensiz.es/phone

P.S.英文看着更容易让人信服,对吧,为什么呢?

##四.注意事项

对CSS规范使用媒体查询时发现:

微信内置浏览器不支持
@media (min-device-width : 320px)
需要修改html meta
width=device-width再用
@media (min-width:480px)

很隐晦的问题,所以千万不要使用min-device-width,看似省事

###参考资料

都链接在上文里了,另外,强烈建议看看完全理解px,dpr,dpi,dip,稳赚不赔

评论

暂无评论

提交评论