一、应该测试的浏览器
- iOS内置Safari
- 安卓webkit4,至少要有2到3个:三星、HTC、其他
- Google Chrome
- 三星Chrome
确认设备内置浏览器的方法:检查用户代理字符串(useragent string, navigator.userAgent),如果包含单词Chrome,就是Chrome,反之是Webkit。
二、视口
- 桌面浏览器中,浏览器窗口就是约束你的CSS布局的视口(初始包含块)。也决定了用户可以看到什么。
- 手机上,桌面视口被拆分成两个:布局视口会限制你的CSS布局;视觉视口会决定用户能看到什么。布局视口一般情况下远大于视觉视口,布局视口的出现为了桌面网站在移动端看起来不至于太丑。
- 移动端还有一个理想视口,对于特定设备上特定浏览器视口的理想尺寸。
- 可以把布局视口的尺寸设置为理想视口。实际上,这是响应式设计的基础。
两个例子说明浏览器的三种视口:
- position: fixed。标准上说:盒子相对于视口的位置是固定的,不会随着滚动而变化。
- vw和vh是相对视口的百分比
第一个中说的『视口』,是指的视觉视口,因为设置为fixed的元素用户再滚动时可以一直看到。
第二个中说的『视口』,是指的布局视口,当用户缩放视觉视口时,其中的元素大小也会随之缩放,显然布局设置宽高的时候不会希望随着用户放大缩小带来额外的计算量。
布局视口用document.documentElement.clientWidth/Height 返回。
视觉视口用window.innerWidth/Height 返回。
三、缩放
缩放在移动设备和桌面端有不同的含义:
- 移动端拖放(注意是拖放)改变视觉视口大小,放大的时候视觉视口缩小,缩小的时候视觉视口放大。布局视口在这个过程中没有变化。
- 桌面端缩放(页面缩放)视觉视口和布局视口同步变化,因为它们是相同的。
值得注意的是,禁止缩放是没有意义也是错的,用户有选择放大页面的权利。
四、分辨率
像素有两个含义,设备像素和CSS像素,为了方便前端工程师,接触到的一般都是CSS像素,可以使用 screen.width 来获取设备像素个数,但是获得的值并不可靠,可能是理想视口的尺寸或者是屏幕设备像素的尺寸,因此无意义。
设备像素比(Device Pixel Ratio, DPR)可以用JS的window.devicePixelRatio或者CSS的device-pixel-ratio来获得,提供的是设备像素个数和理想视口的比。就是在浏览器中调试的时候选择设备下方的比例。这个值不一定是整数。
可以依靠DPR来决定是否使用高分辨率的图片,这一点被响应式图片社区研究得很深,同时博文里面有一篇简要介绍如何使用响应式图片的文章。
DPR的单位是dppx,JS和CSS代码中使用的时候不需要单位,为了支持IE11及以下版本,根据1dppx = 96dpi,写成下面这样:
@media all and ((-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi)) {
// DPR大于等于2时候起效
}
if(window.devicePixelRatio >= 2) {
// DPR大于等于2时候起效
}
值得注意的是,前端工程师倾向于查1.5这个DPR,可以在http://smashed.by/mwhb7 中看到调查结果。
五、媒体查询
首先设置『完美meta视口』:
<meta name=“viewport” content=“width=device-width, initial-scale=1">
其次,可以查询且有用的媒体包括:宽度、设备方向、设备像素比、设备分辨率、设备宽高比。
值得注意的是,em作为单位并没有比px更优秀:em以html元素默认字体大小作为基准,在移动端,根元素字体大小在缩放时不会变化;在桌面端,放大缩小CSS像素尺寸的同时字体大小不会变化,所以em也没有优势。但是em作为单位在很多时候显得比px更有逻辑。
六、移动端CSS预警
移动端浏览器和桌面浏览器对CSS的支持不尽相同,有以下4个原因:
- 桌面端的用例在触摸屏上不存在,或者无法很好的适应触摸屏幕。比如,hover。
- 需要考虑视口时规范并没有说是哪个视口(布局还是视觉?)。比如,vw和vh
- 对独立可滚动层的需求,在资源受限制的移动端更难实现。比如,background-attachment。
- 硬件限制,尤其是涉及内存和GPU的时候。比如,过渡(Transition)和动画(Animation),但是这个的根源在于硬件不在浏览器。这种情况下测试需要去找最古老的设备。
由于这四个原因,移动端浏览器上CSS会存在坑。
- position: fixed。
老版本浏览器因为独立层滚动花费太多资源,因而错误地相对于布局视口固定,新版本浏览器相对于视觉视口固定。移动端中,当写一个顶栏固定、左上角位于(0, 0)、占空间较窄的fixed元素,不会出现什么问题。PPK认为fixed元素再移动端中没有必要,事实上对任何一个较大型的展示网站来说都是极其必要的。另外由于交互设计倾向于去掉汉堡菜单并且将菜单放置于页面底端,这会在safari中出现问题,值得探究。 - overflow: auto。
具有这个样式的元素必须能够独立滚动。几乎所有浏览器都正确实现了这个样式,值得注意的是代理服务器,如opera mini, UC,不支持。因此移动端中最好将这些层展开。 - background-attachment。
多数浏览器只支持fixed和local中的一个。这在移动端是不可靠的。但是它存在的价值之一是用CSS实现视差滚动,想比起JS的实现,性能更好。 - 尺寸单位vw和vh。
vw和vh的大小都是相对布局视口而言。目前为止只在基于Blink渲染引擎的浏览器,以及IE和安卓系统上的FF正确支持了这两个单位,试试这个用了vw和vh的网站的兼容性。所以目前为止慎用,但是这两个单位对响应式设计很有帮助。 - :active和:hover
可以放心使用,虽然移植得失败,但是最坏的情况也只是不起作用罢了。 - 过渡和动画。
H5目前为止不能取代APP的原因之一就是高能耗,一方面来源于浏览器本身,一方面来源于各种效果的实现。幸运的是,目前为止几乎所有移动端浏览器都对CSS3过渡和动画有了很好的支持,所以可以丢弃掉easing.js,大胆使用CSS3动画。
七、触摸和指针
PPK在移动Web手册中对指针(pointer)事件寄予厚望,认为是统一触摸事件和鼠标事件的希望。微软和谷歌大佬在开发出同时带有触摸屏和触摸板的设备之后对指针事件的兴趣逐渐提高。更进一步,指针事件可以考虑扩展到其他设备,比如Wacom绘图板、Kinect体感等,可以预见pointer在未来是一个很好的方向。
但是目前为止,指针事件的支持并不好,目前只在IE中支持。
说回现在应用最多的触摸事件,触摸事件有4种:
- touchstart,用户的手指触摸屏幕的瞬间触发。
- touchmove,用户移动手指的过程中连续触发。
- touchend,用户的手指离开屏幕的瞬间触发。
- touchcancel,含义取决于浏览器,除了谷歌chrome外,大部分浏览器没有处理这个事件,当touchend事件没有被触发的时候,可以将touchend的处理函数绑定到touchcancel上。
触摸事件为什么要区分出来?
因为触摸屏幕的出现带来一种跟鼠标事件(和键盘事件)很不相同的交互方式。
- 触摸事件不连续性。
以下拉菜单为例,鼠标事件可以hover时弹出下拉菜单,鼠标移入菜单并且点选。但是触摸事件不是连续的,如果采用传统的方法,当手指离开屏幕菜单会收回。常用的实践是单击弹出菜单。 - 触摸的多点性。
触摸可以多点触摸,因为这些多点触摸操作常被设备占用,所以不用过于关心。其次每次触摸时候选中的像素是一片而不是单个。不同的浏览器有不同的处理,有些选择中心点,有些则不是。
web事件应该如何发展?
目前用得最多的三种事件是触摸事件、鼠标事件、键盘事件。但是在可预知的未来至少会呈现两个趋势:
- 触摸事件的丰富。
随着苹果3Dtouch的开发,触摸事件可能会新增对压力的支持。 - 其他事件的产生。
智能设备的发展必然产生其他时间:智能车的开关是否需要开关门事件?Kinect体感是否需要手势事件?
更多的事件对前端来说是更大的工作量,为了实现一个事件前端工程师可能不得不重写多次代码。
类比应对浏览器发展的方法(渐进增强和优雅降级),类比应对屏幕尺寸分辨率不同的方法(响应式,某种程度上也是一种渐进增强/减弱),『输入模式的渐进增强』可能是一种趋势。至于PPK曾说用指针事件统一未来的想法,我持消极态度。指针事件或许可以统一鼠标和触摸,但是其他事件难以统一。
八、其他注意事项
- 慎用 Javascript脚本库。类似jQuery这样的脚本库虽然本身很小,但是模块的初始化消耗大量电量:约1/3。
- 一次性请求尽可能多的资源。当浏览器请求资源时,需要约2秒的事件来建立网络连接。
- 添加到主屏幕(Add to Homescreen),Chrome 安卓,iOS Safari
资料参考:PPK,移动Web手册,et al.
作者署名:Hongyang Wang
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
更多内容请关注我的博客:hongyang.space
和我的简书帐号:HongyangWang
网友评论