移动端的一些tip
开发相关
关于viewport
<meta name="viewport" content="name=value,name=value">
//
指令
每对键值对都是一个指令,(ppk 大神的叫法)以下总计共有6对:
width
设置layout viewport的宽度(css px)
initial-scale
设置页面的初始缩放比例同时可以设置layout viewport的宽度
minimum-scale
设置最小缩放比例(指用户能够缩小到多小)
maximum-scale
设置最大缩放比例(指用户能够放大到多大)
height
设置layout viewport的高度,但暂时不怎么被支持
user-scalable
设置是否允许用户放大缩小。
当我们的网页不使用viewport的时候网页在移动端显示的时候基本上看不清楚字体,为什么呢?因为我们将960px(当我们不做设置的时候viewport会自动的把我们的html给规定成980px)的内容压缩到320dpx(非css单位,在移动端中1px带至一个最小显示单位,一屏就是320px)。
解决方案
通过上述的例子我们知道基本上 viewport 的默认宽度是980px,且浏览器会将者 viewport 大小的 html 文档塞进有限的设备宽度内(浏览器会动态计算文档的布局及内容),所以我们看到的东西都很小。
那么我们想要清除的看清文档内的内容怎么办 ,没错,缩小 viewport 的大小,什么原理?
当我们缩小 viewport 的宽度的时候文档的宽度也对应的被缩小,即一样的设备宽度,我显示的东西少了(这时候浏览器重新计算文档布局及内容)可以看到的结果是字体被放大了,内容都被放大了!
详细解释
- [x] width
可以用width来设置viewport的宽度,以替代那些不合适的默认宽度。我们可以给其设定一个固定大小,但设定成device-width更加明智一些,这样我们可以兼容不同大小的屏幕。采用了之后就是我们上面所说的效果,虽然是显示的东西变少了但是我的字体变大了! - [x] initial-scale
在移动设备上,用户有时会缩放,当页面缩放时,viweport的像素尺寸也会响应的改变,单css尺寸不会变。
比如,在一个400px宽的Viewport中有一个元素,设定 100px;,这时该元素就横跨了1/4的屏幕。如果用户把页面放大到两倍大小,这时Viewport宽度变成了200px,但元素仍然宽100个CSS像素。这时这个元素就占了半个屏幕了。
滚动方式
页面的滚动位置分为两种,一种是滚动body,另一种固定body的高度为100%,在main中滚动。
-
滚动body:页面的地址会随着body的滚动隐藏起来,并且在android设备中,滚动body会更加的流畅。(把body设置为overflow就行了)这种情况比较适合长列表页面,整个页面除了herder和footer之外都需要滚动,但很多时候我们只希望页面的某个元素滚动,这个时候就采取第二种布局方式。
-
body高度设置为100%:这种方法有许多种实现方式
- [x] fixed定位 -- 头部尾部都设置为fixed定位
- [x] absolute定位
- [x] flex定位
这里面也存在一些需要注意的地方,在移动端,如果fixed定位结点后面紧接着跟着兴地结点是可滚动的(也就是设置了overflow为true),那么fixed结点会被其后的兄弟结点遮住
fixed 与 input
在移动端开发中,在有input元素的标签页中使用fixed定位时会出现一些问题。 在ios上,当点击input标签获取焦点唤起软键盘的时候fixed定位会暂时失效,或者理解为变为了absolute定位,在含有滚动的页面会和其他结点一起滚动。所以在含有input元素的页面中使用absolute更好。
compositionstart和compositionend事件
在开发中我们经常要对表单元素进行输入限制,比如特殊的字符(也有xss的防范功能),我们会监听input事件。但是,在ios中input事件会截断非直接输入,比如:输入[焦贵彬]中间过程中会输入拼音,每次输入一个字母都会触发input事件,然而在没有点击选定按钮之前都会截断,也就是会触发很多次。这时候就需要我们说的两个事件。
compositionstart 事件在用户开始进行非直接输入的时候触发,而在非直接输入结束,也即用户点选候选词或者点击「选定」按钮之后,会触发 compositionend 事件。
关于性能
使用css3动画,开启硬件加速(存在需要注意的地方)
css3动画会新建一个图层,另外部分css3动画会调用GPU,得到性能上的提升.
触发
- 3d 透视或视图变换(perspective transform)css属性
- 使用加速视频解码的元素
- 拥有3d(webGL)上下文或2d上下文的元素(carvers)
- 混合插件(如flash)
- 对自己的opacity做css动画或使用一个动画webkit变换元素
- 拥有加速 CSS 过滤器的元素
- 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
- 元素有一个 ** z-index ** 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
上面有提到需要注意一些地方,就是他会将后面的一些不需要新建图层的元素新建图层,使性能不仅没有提升反而出现了一些隐患!
如何来看到css3动画新建的图层
在chrome 中选择open drawer(版本不同会不一样,有些版本下直接在控制台的设置中 more tools --> rednering)选择rendering,然后选择打开layer boerders ,现在在我们的浏览器上就可以看到一些黄色的框框,这个就是我们所谓的复合层,表示被放到了一个新的图层中渲染。
隐患
注意触发新建图层的最后一条,它的意思是如果有一个元素,它的兄弟元素复合层中渲染,而这个兄弟元素的z-index较小,那么这个元素(不管是否应用了硬件式加速)也会被放到复合层中,那么浏览器很有可能给复合层之后的所有相对或绝对定位的元素都创建一个复合层来渲染,于是就有了这样的情形-- 页面上很多元素都启用了GPU加速,反而导致了页面非常的卡顿
解决方案
- 在启用css3动画的元素上增加position:relative和z-index:1,这种做法的原理是认为提升动画元素的z-index,让浏览器知道这个元素的层序,就不会很傻逼的把其他z-index比他高的元素耶弄到复合层中了
- 上面说了一些需要注意的地方,但是总体来说我们还是会采用一些css3的动画去调用GPU,比如translate-Z:0;可是此时我们并不是要旋转,这是一种欺骗浏览器的行为。此时我们可以关注一下will-change
/* 关键字值 */ will-change: auto; will-change: scroll-position; // 告知浏览器会有滚动 will-change: contents; // 告知浏览器内容或动画变化了 will-change: transform; /* <custom-ident>示例 */ will-change: opacity; /* <custom-ident>示例 */ will-change: left, top; /* 两个<animateable-feature>示例 */ /* 全局值 */ will-change: inherit; will-change: initial; will-change: unset;
适当的使用touch事件代替click事件
- touch事件触发的流程:touchstart -> touchmove -> touchend -> click
- 触发时机:click在dom上手指触摸开始,且手指未曾在屏幕上移动(某些浏览器允许移动一个非常小的值)且在这个在这个dom上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短才能触发。
减少媒体查询
如果使用的是rem的单位(相当于根元素的字体大小来缩放)因为这样有两个明显的缺点 1.适配屏幕的尺寸不是连续的 2. 在自己的css文件中添加打断的这样查询代码。增加了css文件的体积。
- 参考淘宝的移动端的页面适配规则,使用js获取客户端的宽度,根据设计稿原型动态计算计算font-size的值
other
- 避免使用css渐变阴影效果
- 不滥用Web字体
Web字体需要下载,解析,重绘当前页面,尽量减少使用。
参考
- 饿了么前端
- 张鑫旭博客