-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathweb
More file actions
264 lines (210 loc) · 15.1 KB
/
web
File metadata and controls
264 lines (210 loc) · 15.1 KB
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
移动端开发
Zlaojie
2019.11.19 20:29:10
字数 2,530
阅读 0
编辑文章
Pixel移动端开发像素知识
px:CSS Pixel逻辑像素,浏览器使用的抽象单位,实际开发
dp,pt:device independent pixels设备无关像素
dpr:devicePixelRatio设备像素缩放比
计算公式:1px=(dpr)^2 *dp
image.png
DPI:打印机每英寸可以喷的墨汁点(印刷行业)
PPI:屏幕每英寸的像素数量,即单位英寸内的像素密度。
目前,在计算机显示设备参数描述上,二者意思表达的是一样的。
image.png
image.png
image.png
image.png
image.png
可视角度大小,决定了用户可视范围的大小以及最佳观赏角度。
Viewport
为什么渲染时要有Viewport——为了排版正确
image.png
image.png
image.png
手机浏览器默认为我们做了两件事:
一、页面渲染在一个980px(以iOS为例)的Viewport
二、缩放
不适用默认的980px的布局viewpoint
宽度不可控制,不同系统不同设备的默认值都可能不同
页面缩小版显示,交互不友好
链接不可点
有缩放,缩放后又有滚动
通过meta标签来改变默认viewpoint
<meta name="viewport" content="name=value,name=value">
image.png
image.png
查看默认的布局viewport:document.body.clientWidth
查看度量viewport:window.innerWidth
device-width:布局viewport等于设备宽度
<meta name="viewport" content="width=device-width">
查看缩放比:window.innerWidth/document.body.clientWidth
希望缩放比统一
缩放比为1:度量viewport等于布局viewport
initial-scale自带width=device-width
<meta name="viewport" content="width=device-width, initial-scale=1">
移动Web最佳viewport设置
布局viewport=设备宽度=度量viewport
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
设计移动Web
image.png
使页面有良好的自适应性——固定布局和流体布局
Flexbox弹性盒子布局
兼容性:
iOS可以使用最新的flex布局
Android4.4以下,只能兼容旧版的flexbox布局
Android4.4及以上。可以使用最新的flex布局
image.png
响应式布局
媒体查询
推荐screen或者all
image.png
设计点一:百分比布局
设计点二:弹性图片
设计点三:重新布局,显示与隐藏
1.同比例缩减元素尺寸
2.调整页面结构布局
3.隐藏冗余的元素
经常需要切换元素使用绝对定位,减少重绘提高渲染性能。
响应式布局性能不是最优的,一个页面包含所有设备不同屏幕的样式和图片,当一个移动设备访问一个响应式的页面,就会下载PC,笔记本,iPad等不同设备对应的样式,会造成冗余。
解决一像素边框问题:
UI设计师要求的1px是指设备的物理像素1px,而CSS里记录的像素是逻辑像素,它们之间存在一个比例关系,可以用javascript中的window.devicePixelRatio来获取,也可以用媒体查询的-webkit-min-device-pixel-ratio来获取。当然,比例多少与设备相关。
在手机上border无法达到我们想要的效果。这是因为devicePixelRatio特性导致,iPhone的devicePixelRatio==2,而border-width: 1px描述的是设备独立像素,所以,border被放大到物理像素2px显示,在iPhone上就显得较粗。
1px使用2dp渲染,viewport的设置和屏幕物理分辨率是按比例而不是相同的. 移动端window对象有个devicePixelRatio属性, 它表示设备物理像素和css像素的比例, 在retina屏的iphone手机上, 这个值为2或3, css里写的1px长度映射到物理像素上就有2px或3px那么长。
媒体查询利用设备像素比缩放,设置小数像素
IOS8下已经支持带小数的px值, media query对应devicePixelRatio有个查询值-webkit-min-device-pixel-ratio, css可以写成这样
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border { border: 0.333333px solid #999 }
}
【缺点】对设备有要求,小数像素目前兼容性较差。
2. viewport + rem 方案
该方案是对上述方案的优化,整体思路就是利用viewport + rem + js 动态的修改页面的缩放比例,实现小于1像素的显示。在页面初始化时,在头部引入原始默认状态如下:
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
接下来的任务就是js的动态修改缩放比 以及 实现rem根元素字体大小的设置。
var viewport = document.querySelector("meta[name=viewport]")
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no')
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no')
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.333333333, maximum-scale=0.333333333, minimum-scale=0.333333333, user-scalable=no')
}
var docEl = document.documentElement;
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
docEl.style.fontSize = fontsize;
【缺点】以为缩放涉及全局的rem单位,比较适合新项目,对于老项目可能要涉及到比较多的改动。
3. 设置 border-image 方案
.border-image-1px {
border-width: 1px 0px;
-webkit-border-image: url("border.png") 2 0 stretch;
border-image: url("border.png") 2 0 stretch;
}
【解释】border-width 指定边框的宽度,可以设定四个值,分别为上右下左border-width: top right bottom left。
border-image 该例意为:距离图片上方2px(属性值上没有单位)裁剪边框图片作为上边框,下方2px裁剪作为下边框。距离左右0像素裁剪图片即没有边框,以拉伸方式展示
结合起来就是:在边框图片中,裁剪图片上下方的2个像素宽度作为上下边框,并展示在宽度为1个像素的边框空间里。左右没有边框。 注意这里的1个像素是特殊的,专指物理像素,而平时设定的长宽1px则表示逻辑像素(该观点为个人理解)。
你可能并没有理解,裁剪边框是什么鬼?为啥还要裁剪?border-image确实是个很难理解的属性,是去w3c看了之后更加蒙圈了。w3c内容提炼的太精致了,但解释根本就不够。因此奉上张鑫旭老师 border-image详解 一文,特别要理解九宫格裁剪法。
当然,这种方式引入了图片,我们还能将图片装换成base64形式表现
.border-image-1px {
border-width: 1px 0px;
-webkit-border-image: url("data:image/png;base64,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") 2 0 stretch;
border-image: url('如上');
}
【缺点】需要制作图片,圆角可能出现模糊
4. background-image 渐变实现
除了使用图片外,当然也能使用纯css来实现,百度糯米团就是采用的这种方案。
.border {
background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
linear-gradient(270deg, red, red 50%, transparent 50%),
linear-gradient(0deg, red, red 50%, transparent 50%),
linear-gradient(90deg, red, red 50%, transparent 50%);
background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background-repeat: no-repeat;
background-position: top, right top, bottom, left top;
padding: 10px;
}
【思路】将原本1个物理像素的边框大小利用线性渐变分割成几个部分(百分比控制),实现小于1像素效果
【解释】linear-gradient指定线性渐变,接受大于等于3个参数,第一个为渐变旋转角度,第二个开始为渐变的颜色和到哪个位置(百分比)全部变为该颜色,该例子中,第一句就是,渐变方向旋转180度,即从上往下(默认为0度从下往上),从红色开始渐变,到50%的位置还是红色,再渐变为继承父元素颜色。
【缺点】因为每个边框都是线性渐变颜色实现,因此无法实现圆角
5. box-shadow 方案
利用阴影也可以实现,优点是没有圆角问题,缺点是颜色不好控制
div {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
【理解】来回顾一下box-shadow属性的用法。
box-shadow: h-shadow v-shadow [blur] [spread] [color] [inset];
参数分别表示: 水平阴影位置,垂直阴影位置,模糊距离, 阴影尺寸,阴影颜色,将外部阴影改为内部阴影,后四个可选。该例中为何将阴影尺寸设置为负数?设置成-1px 是为了让阴影尺寸稍小于div元素尺寸,这样左右两边的阴影就不会暴露出来,实现只有底部一边有阴影的效果。从而实现分割线效果(单边边框)。
6. transform: scale(0.5) 方案 - 推荐: 很灵活
在以上的用法种,无非逃不开一种思想,就是将1px缩小为0.5px来展示,然而。0.5px并不是所有的设备或浏览器都支持,就考虑用媒体查询或viewport将其缩放比例。其实1像素问题的产生基本发生在设置边框或分割线的时候,场景并不覆盖全局样式,因此,直接缩放需要设置的元素,才是我们真正需要的。tranform就能实现这个需求。
设置height: 1px,根据媒体查询结合transform缩放为相应尺寸。
div {
height:1px;
background:#000;
-webkit-transform: scaleY(0.5);
-webkit-transform-origin:0 0;
overflow: hidden;
}
2.用::after和::befor,设置border-bottom:1px solid #000,然后在缩放-webkit-transform: scaleY(0.5);可以实现两根边线的需求
div::after{
content:'';width:100%;
border-bottom:1px solid #000;
transform: scaleY(0.5);
}
3.用::after设置border:1px solid #000; width:200%; height:200%,然后再缩放scaleY(0.5); 优点可以实现圆角,京东就是这么实现的,缺点是按钮添加active比较麻烦。
.div::after {
content: '';
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}
# 6.5 媒体查询 + transfrom 对方案1的优化
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
相对单位rem
为了适应各大屏幕的手机,px略显固定,不能根据尺寸的大小而改变,使用相对单位更能体验页面兼容性。
em:是根据父节点的font-size为相对单位
rem:是根据html的font-size为相对单位
em在多层嵌套下,变得难以操作,rem更加能作为全局统一设置的度量
设置rem的基值:rem=screen.width/20
不适用rem的情况:font-size,因为字体的大小是趋向于阅读的实用性,并不适合于排版布局。
同理趋向于一些固定的元素的特性,我们不使用rem而改为使用px去确保在不同屏幕上表现一致(跟rem的目的相反)
300ms的故事:移动web页面上的click事件响应都要慢上300ms,可以使用Tap事件代替click事件
image.png
Tap“点透”的bug
image.png
在300ms结束之前不要触发到click
image.png
touchend没有touches对象数组
image.png
image.png
image.png
image.png
image.png
image.png