移动WEB开发之流式布局

移动端基础

浏览器现状

PC端常见浏览器
360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器、搜狗浏览器、IE浏览器。

移动端常见浏览器
UC浏览器、QQ浏览器、欧朋浏览器、百度手机浏览器、360安全浏览器、谷歌浏览器、搜狗手机浏览器、猎豹浏览器、以及其他杂牌浏览器。

国内的UC和QQ,百度等手机浏览器都是根据Webkit修改过来的内核,国内尚无自主研发的内核,就像国内的手机操作系统都是基于Android开发的一样。

总结:兼容移动端主流浏览器,处理Webkit内浏览器即可。

手机屏幕现状

  • 移动端设备屏幕尺寸非常多,碎片化严重
  • Android设备有多种分辨率:480 * 800,480 * 854,540 * 960,720 * 1280,1080 * 1920等,还有传说中的2k,4k屏
  • 近年来iPhone的碎片化也加剧了,其设备的主要分率有:640 * 960,640 * 1136,750 * 1334,1242 * 2208等作为开发者无需关注这些分辨率,因为我们常用的尺寸单位是px

常见移动端屏幕尺寸

注:作为前端开发,不建议大家去纠结dp,dpi,pt,ppi等单位

移动端调试方法

  • Chrome Devtools(谷歌浏览器)的模拟手机调试
  • 搭建本地web服务器,手机和服务器一个局域网内,通过手机访问服务器
  • 使用外网服务器,直接IP或域名访问

总结

  • 移动端浏览器我们主要对webkit内核进行兼容
  • 我们现在开发的移动端主要针对手机端开发
  • 现在移动端碎片化比较严重,分辨率和屏尺寸大小不ー
  • 学会用谷歌浏览器模拟手机界面以及调试

视口

视口(viewport)就是浏览器显示页面内容的屏幕区域。视口可以分为布局视口、视觉视口和理想视口

布局视口 layout viewport

  • 一般移动设备的浏览器都默认设置了一个布局视口,用于解决早期的PC端页面在手机上显示的问题。
  • iOS、Android基本都将这个视口分辨率设置为980px,所以PC上的网页大多都能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。

视觉视口 visual viewport

  • 字面意思,它是用户正在看到的网站的区域。注意:是网站的区域
  • 我们可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度

理想视口 ideal viewport

  • 为了使网站在移动端有最理想的浏览和阅读宽度而设定
  • 理想视口,对设备来讲,是最理想的视口尺寸
  • 需要手动添写meta视口标签通知览器操作
  • meta视口标签的主要目的:布局视口的宽度应该与理想视口的宽度一致,简单理解就是设备有多宽,我们布局的视口就多宽

总结

  • 视口就是浏览器显示页面内容的屏幕区域
  • 视口分为布局视口、视觉视口和理想视口
  • 我们移动端布局想要的是理想视口就是手机屏幕有多宽,我们的布局视口就有多宽
  • 想要理想视口,我们需要给我们的移动端页面添加meta视口标签
1
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

标准的viewport设置

  • 视口宽度和设备保持一致
  • 视口的默认缩放比例1.0
  • 不允许用户自行缩放
  • 最大允许的缩放比例1.0
  • 最小允许的缩放比例1.0

二倍图

物理像素&物理像素比

  • 物理像素点指的是屏幕显示的最小颗粒,是物理真实存在的。这是厂商在出厂时就设置好了,比如苹果6、7、8是750*1334
  • 我们开发时候的1px不是一定等于1个物理像素的
  • PC端页面,1个px等于1个物理像素的,但是移动端就不尽相同
  • 一个px能显示的物理像素点的个数,称为物理像素比或屏幕像素比

注:

  • 物理像素,就是我们说的分辨率,iPhone8的物理像素是750
    在iPhone8里面,1px开发像素 = 2个物理像素
  • PC端和早期的手机屏幕/普通手机屏幕:1CSS像素 = 1 物理像素
  • Retina(网膜屏幕)是一种显示技术,可以把更多的物理像素点压缩在一块屏幕里面,从而达到更高的分辨率,并提高屏幕显示的细腻程度

多倍图

  • 对于一张50px*50px的图片,在手机Retina屏中打开,按照刚才的物理像素比会放大倍数,这样会造成图片模糊
  • 在标准的viewport设置中,使用倍图来提高图片质量,解决在高清设备中的模糊问题
  • 通常使用二倍图,因为iPhone6、7、8的影响,但是现在还存在3倍图、4倍图情况,这个看实际公司需求
  • 背景图片注意缩放问题
1
2
3
4
5
6
7
8
9
10
/* 在iPhone8下面 */
img{
/* 原始图片100*100px */
width:50px;
height:50px;
}
.box{
/* 原始图片100*100px */
background-size:50px 50px
}

背景缩放background-size

background-size属性规定背景图像的尺寸

1
background-size:背景图片宽度 背景图片高度;
  • 单位:长度 | 百分比 | cover | contain
  • cover把背景图像扩展至足够大,以使背景图像完全覆盖背景区域
  • contain把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域

多倍图切图 cutterman

  • @3X 3倍图
  • @2X 2倍图
  • @1X 1倍图原图

移动端开发选择

移动端主流方案

  • 单独制作移动端页面(主流)
    如:京东商城手机版、淘宝触屏版、苏宁易购手机版
  • 响应式页面兼容移动端(其次)
    三星手机官网

单独移动端页面(主流)

通常情况下,网址域名前面加m(mobile)可以打开移动端。通过判断设备,如果是移动设备打开,则跳到移动端页面。

响应式兼容PC移动端

三星电子官网:https://www.samsung.com/cn/。通过判断屏幕亮度来改变样式,以适应不同终端。
缺点:制作麻烦,需要消耗很大精力去调兼容性问题。

总结

现在市场常见的移动端开发有 单独制作移动端页面 和 响应式页面 两种方案,现在市场主流的选择还是单独制作移动端页面。

移动端技术解决方案

移动端浏览器

移动端浏览器基本以webkit内核为主,因此我们就考虑webkit兼容性问题,我们可以放心使用H5标签和CSS3样式,同时我们浏览器的私有前缀我们只需要考虑添加webkit即可。

CSS初始化 normalize.css

移动端CSS初始化推荐使用normalize.css

  • Normalize.css:保护了有价值的默认值
  • Normalize.css:修复了浏览器的bug
  • Normalize.css:是模块化的
  • Normalize.css:拥有详细的文档

官网地址:http://necolas.github.io/normalize.css/

CSS3盒子模型 box-sizing

  • 传统模式宽度计算:盒子的宽度=CSS中设置的 width + border + padding
  • CSS3盒子模型:盒子的宽度=CSS中设置的宽度width里面包含了border和padding
  • 也就是说,我们的CSS3中的盒子模型,padding和border不会撑大盒子了
1
2
3
4
/* css3盒子模型 */
box-sizing:border-box;
/* 传统盒子模型 */
box-sizing:content-box;

传统orCSS3盒子模型?

  • 移动端可以全部CSS3盒子模型
  • PC端如果完全需要兼容,我们就用传统模式。如果不考虑兼容性,我们就选择CSS3盒子模型

特殊样式

1
2
3
4
5
6
7
8
9
/*css3盒子模型*/
box-sizing: border-box;
-webkit-box-sizing: border-box;
/*点击高亮我们需要清除清除 设置为transparent完成透明*/
-webkit-tap-highlight-color: transparent;
/*在移动端浏览器默认的外观在iOS上加上这个属性オ能给按钮和输入框自定义样式*/
-webkit-appearance: none;
/*禁用长按页面时的弹出菜单*/
img,a{-webkit-touch-callout: none;}

移动端常见布局

移动端技术选型

1. 单独制作移动端页面(主流)

  • 流式布局(百分比布局)
  • flex弹性布局(强烈推荐)
  • less+rem+媒体查询布局
  • 混合布局

2. 响应式页面兼容移动端(其次)

  • 媒体查询
    bootstrap

流式布局(百分比布局)

  • 流式布局,就是百分比布局,也称非固定像素布局
  • 通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充
  • 流式布局方式是移动web开发使用的比较常见的布局方式
  • max-width 最大宽度(max-height最大高度)
  • min-width 最小宽度(min-height最小高度)

手机端京东案例:
HTML部分

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- 引入我们的css初始化文件 -->
<link rel="stylesheet" href="css/normalize.css">
<!-- 引入我们首页的css -->
<link rel="stylesheet" href="css/index.css">
<title>Document</title>
</head>

<body>
<!-- 顶部 -->
<header class="app">
<ul>
<li>
<img src="images/close.png" alt="">
</li>
<li>
<img src="images/logo.png" alt="">
</li>
<li>打开京东App,购物更轻松</li>
<li>立即打开</li>
</ul>
</header>
<!-- 搜索 -->
<div class="search-wrap">
<div class="search-btn"></div>
<div class="search">
<div class="jd-icon"></div>
<div class="sou"></div>
</div>
<div class="search-login">登陆</div>
</div>
<!-- 主体内容部分 -->
<div class="main-content">
<!-- 滑动图 -->
<div class="slider">
<img src="upload/banner.dpg" alt="">
</div>

<!-- 小家电品牌日 -->
<div class="brand">
<div>
<a href="#">
<img src="upload/pic11.dpg" alt="">
</a>
</div>
<div>
<a href="#">
<img src="upload/pic22.dpg" alt="">
</a>

</div>
<div>
<a href="#">
<img src="upload/pic33.dpg" alt="">
</a>

</div>
</div>
<!-- nav部分 -->
<nav class="clearfix">
<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav2.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav3.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

<a href="">
<img src="upload/nav1.webp" alt="">
<span>京东超市</span>
</a>

</nav>
<!-- 新闻模块 -->
<div class="news">
<a href="#">
<img src="upload/new1.dpg" alt="">
</a>
<a href="#">
<img src="upload/new2.dpg" alt="">

</a>
<a href="#">
<img src="upload/new3.dpg" alt="">

</a>
</div>
</div>
</body>

</html>

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
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
body {
width: 100%;
min-width: 320px;
max-width: 640px;
margin: 0 auto;
font-size: 14px;
font-family: -apple-system, Helvetica, sans-serif;
color: #666;
line-height: 1.5;
}


/*点击高亮我们需要清除清除 设置为transparent 完成透明*/

* {
-webkit-tap-highlight-color: transparent;
}


/*在移动端浏览器默认的外观在iOS上加上这个属性才能给按钮和输入框自定义样式*/

input {
-webkit-appearance: none;
}


/*禁用长按页面时的弹出菜单*/

img,
a {
-webkit-touch-callout: none;
}

a {
color: #666;
text-decoration: none;
}

ul {
margin: 0;
padding: 0;
list-style: none;
}

img {
vertical-align: middle;
}

div {
/* css3 盒子模型 */
box-sizing: border-box;
}

.clearfix:after {
content: "";
display: block;
line-height: 0;
visibility: hidden;
height: 0;
clear: both;
}

.app {
height: 45px;
}

.app ul li {
float: left;
height: 45px;
line-height: 45px;
background-color: #333333;
text-align: center;
color: #fff;
}

.app ul li:nth-child(1) {
width: 8%;
}

.app ul li:nth-child(1) img {
width: 10px;
}

.app ul li:nth-child(2) {
width: 10%;
}

.app ul li:nth-child(2) img {
width: 30px;
vertical-align: middle;
}

.app ul li:nth-child(3) {
width: 57%;
}

.app ul li:nth-child(4) {
width: 25%;
background-color: #F63515;
}


/* 搜索 */

.search-wrap {
position: fixed;
overflow: hidden;
width: 100%;
height: 44px;
min-width: 320px;
max-width: 640px;
}

.search-btn {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 44px;
}

.search-btn::before {
content: "";
display: block;
width: 20px;
height: 18px;
background: url(../images/s-btn.png) no-repeat;
background-size: 20px 18px;
margin: 14px 0 0 15px;
}

.search-login {
position: absolute;
right: 0;
top: 0;
width: 40px;
height: 44px;
color: #fff;
line-height: 44px;
}

.search {
position: relative;
height: 30px;
background-color: #fff;
margin: 0 50px;
border-radius: 15px;
margin-top: 7px;
}

.jd-icon {
width: 20px;
height: 15px;
position: absolute;
top: 8px;
left: 13px;
background: url(../images/jd.png) no-repeat;
background-size: 20px 15px;
}

.jd-icon::after {
content: "";
position: absolute;
right: -8px;
top: 0;
display: block;
width: 1px;
height: 15px;
background-color: #ccc;
}

.sou {
position: absolute;
top: 8px;
left: 50px;
width: 18px;
height: 15px;
background: url(../images/jd-sprites.png) no-repeat -81px 0;
background-size: 200px auto;
}

.slider img {
width: 100%;
}


/* 品牌日 */

.brand {
overflow: hidden;
border-radius: 10px 10px 0 0;
}

.brand div {
float: left;
width: 33.33%;
}

.brand div img {
width: 100%;
}


/* nav */

nav {
padding-top: 5px;
}

nav a {
float: left;
width: 20%;
text-align: center;
}

nav a img {
width: 40px;
margin: 10px 0;
}

nav a span {
display: block;
}


/* news */

.news {
margin-top: 20px;
}

.news img {
width: 100%;
}

.news a {
float: left;
box-sizing: border-box;
}

.news a:nth-child(1) {
width: 50%;
}


/* .news a:nth-child(2),
.news a:nth-child(3),
{
width: 25%;
} */


/* n+2 就是从从2个往后面选 */

.news a:nth-child(n+2) {
width: 25%;
border-left: 1px solid #ccc;
}


/* .news a:nth-child(3) {
width: 25%;
} */

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!