Classical Cases in Mobile Web Development

Introduction

本文目标是介绍在移动 web 开发中,遇到的一些常见的布局、样式、事件、动画等方面的问题。

  1. Layout & Style
  2. Events
  3. Animation

Layout

(1) REM

这个单位根据的是 html 根节点的 font-size 的大小。

(2) 文本上下垂直居中

  • table 方式:
1
2
3
display: table-cell;
text-align: center;
vertical-align: middle;
  • flex 方式:
1
2
3
4
display:-webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
text-align:center;

(3) 多行文本

1
2
3
4
5
6
7
div {
display: -webkit-box;
text-overflow: ellipsis;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow : hidden;
}

(4) Retina 高清图片

1
2
3
4
div {
background-image: url(no-image-set.png);
background: image-set(url(foo-lowres.png) 1x,url(foo-highres.png) 2x) center;
}

不支持 image-set 时解析的是 background-image。

(5) 背景透明

1
background: rgba(0, 0, 0, 0.8);

用opacity 会连同文字一起变的透明。

(6) 阻止字体自动调整

1
2
3
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {
-webkit-text-size-adjust:none;
}

(7) 点击抖动

1
-webkit-tap-highlight-color:rgba(0, 0, 0, 0);

(8) 取消 a 标签点击时虚线

1
outline: none;

(9) 禁止选中

1
2
3
4
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;

android机型上,点击会触发选中。
这一点在一些小的icon上使用,用户体验较好。

(10) 禁止缩放

1
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />

(11) 禁止 标签弹出浏览器选项

1
-webkit-touch-callout: none;

(12) 处理吸顶元素 fix 定位同时键盘弹起

参考 m.taobao.com,input元素弹起时,下方用一个遮罩,禁止上下滚动,这样页面高度和浏览器高度相同,
键盘弹起时,不会出现吸顶的元素错位的情况。

1
2
3
4
5
6
7
8
9
10
$body.css({
'height': window.innerHeight + 'px',
'overflow': 'hidden'
});
// 禁止滚动
$body.on('touchmove', function(e) {
e.preventDefault();
return false;
});

(13)IOS 8以上1px border过粗问题

根据 userAgent 判断 IOS 设备,在 html 或 body 上加上 id="ios"。需要对边框进行处理的时候,加上 global-border 的 class 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@media (-webkit-min-device-pixel-ratio: 2){
#ios {
.global-border {
border-width:0.5px;
}
}
}
@media (-webkit-min-device-pixel-ratio: 3){
#ios {
.global-border {
border-width:0.7px;
}
}
}

(14)禁止自动转码

1
<meta name="format-detection" content="telephone=no"/>

(15)CSS 三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*箭头向上*/
.arrow-up {
width:0;
height:0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #fff;
}
/*箭头向下*/
.arrow-down {
width:0;
height:0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #0066cc;
}
/*箭头向左*/
.arrow-left {
width:0;
height:0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid yellow;
}
/*箭头向右*/
.arrow-right {
width:0;
height:0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid green;
}

Events

(1) 点击穿透

参考 点击穿透

(2) iOS 键盘

1
2
3
<input type="text"> <!-- 数字键盘 -->
<input type="text" pattern="[0-9]*"> <!-- 数字键盘,只有 0-9 没有 +/- -->
<input type="url"> <!-- 地址 键盘上含有 .com 按键 -->

iOS 支持的键盘类型还有很多,例如 添加属性 autocapitalize="off",则取消首字母大写。

支持的键盘类型

控制各种键盘展示

还可以消除原生外观,自定义键盘样式

1
-webkit-appearance: none;

(3) IScroll

滚动元素 设置 display: none 再改为 display: block 的时候会导致IScroll无法滚动的问题

原因:不在文档流中显示的元素offset() 得到值为0,滚动动画不生效

需要修改IScroll的源码,检测 DOM 的改变。

(4) 局部滚动broken

fix定位可能导致滑动不流畅,在iOS上设置以下属性,需要同时绑定touchstart事件

1
-webkit-overflow-scrolling: touch

bug 场景描述见 stackoverflow

Animation

(1) 硬件加速

1
-webkit-transform:translate3d(0, 0, 0);

android 对 translate3d 动画效果明显比 iOS 要弱。
尽可能让动画元素用 absolute 定位。

(2) 动画函数

一个 fadeIn 效果,摘自 animate.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.animated {
-webkit-animation-duration: 1s;
animation-duration: 1s; /* 事件间隔 1秒 */
-webkit-animation-fill-mode: both;
animation-fill-mode: both; /* 动画开始和结束之外的状态 */
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
100% {
opacity: 1;
}
}
.fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
}

(3) iOS 多边形裁切

1
-webkit-clip-path: polygon(0px 0px, 100px 0, 0 100px);

(4) 动画闪烁问题

1
2
3
4
5
6
7
8
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;

3D 动画由于默认情况下,是可以看到后面的元素的,因为视差,会造成闪烁情况。
上述样式可以隐藏后面的元素。