言成言成啊 | Kit Chen's Blog

移动web适配问题以及解决方案

2019-09-30

一、移动web开发遇到的问题

设备划分:

浏览器私有前缀:

平板、手机、电脑端,不同的页面有不同的需求。其实可以做出来几套方案,通过判断设备的类型,选择合适的方案。

但是,这样会耗费大量的人力、财力。所以,接下来,总结三种比较流行的解决web适配的布局。

二、移动web适配解决方案

一、流式布局(百分比布局)

视觉窗口:viewport(webstorm中,viewport标签生成快捷键——vp tab),是移动端特有的,这是一个虚拟的区域,承载网页的浏。

浏览器承载viewport,viewport承载网页。

下面这个例子,就会自适应。

1
2
3
4
5
6
7
8
9
10
11
12
.box {
width:100%;
height:500px;
background-color:pink;
}
<div class="box">
流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流
式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式
流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局布局
流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流
流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局流式布局式布局流式布局
</div>

适配设置:

如果任何设置都没有,默认走得就是viewport上的默认设置,可以不用默认的viewport设置,去设置新的viewport设置,达到适配的要求。

1
<meta name="viewport">//这个最好紧接着编码设置

viewport功能:

  1. width:可以设置宽度
  2. height:可以设置高度
  3. initial-scale:可以设置默认的缩放比例
  4. user-scalable:可以设置是否允许用户自行缩放
  5. maximum-scale:可以设置最大缩放比例
  6. minimum-scale:可以设置最小缩放比例
1
在<meta name="viewport" content="">中设置,content里面有以上属性

可以使用jquery,但是不建议,jquery做了很多桌面浏览器的兼容问题,特别是兼容ie浏览器,但是移动端没有ie浏览器

主流浏览器:chrome、火狐、safari浏览器、百度、360、qq

移动端使用h5 api或者zepto.js的库(基于高版本浏览器开发)

移动端常用布局是非固定像素布局,防止内容溢出,防止出现滚动条,提高用户体验

1
box-sizing:border-box;

一般移动端是要取消点击时的高亮的

1
2
3
4
/*取消高亮*/
tap-highlight-color:transparent;
-webkit-tap-highlight-color: transparent;
/*transparent表示全透明*/

关于图片下间隙

1
2
3
<div class="box">
<img src="../images/banner_1.png" alt="">
</div>

div高度为228px,图片高度为224px,会多出来4px

因为:

img为行内块元素,跟文字基线对齐。比如,agx,g下面的尾巴就是多出来的下间隙。下面提出几种解决方案(任选其一):

  1. 设置display:block;
  2. 设置font-size:0;
  3. 设置line-height:0;
  4. 设置vertical-align随便一个值都行

两栏自适应

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
<style>
.box1 {
float:left;
width:100px;
height:100px;
background: pink;
}
.box2 {
width:200px;
height:200px;
background: blue;
float:left;
}
.box3 {
/*overflow的目的是为了让这个元素绝对绝缘 bfc*/
overflow:hidden;
}
</style>
<div class="box1"></div>
<!--<div class="box2"></div>-->
<div class="box3">
1111111内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
</div>

去掉overflow就会形成文本环绕,加上overflow的目的是为了让这个元素绝对绝缘

二、响应式布局(bootstrap)

响应式容器:

响应式开发的原理bootstrap。

假如有以下需求,

  1. 超小屏768px以下,容器宽度100%,背景蓝色
  2. 小屏768px-992px,当前容器宽度750px,背景绿色
  3. 中屏992px-1200px,当前容器宽度970px,背景红色
  4. 大屏1200px以上,当前容器宽度1170px,背景黄色

要实现以上需求,可以通过媒体查询

使用媒体查询@media能针对不同屏幕区间设置不同的布局和样式(扩展:@keyframes帧动画,@font-face设置字体)

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
<div class="container"></div>
<style>
* {
margin:0;
padding:0;
}
.container {
width:1000px;
height:1000px;
background-color: pink;
margin:0 auto;
}
/*使用媒体查询能针对不同屏幕区间设置不同的布局和样式*/
/*如何使用媒体查询 关于媒体查询 @media*/
/*@keyframes帧动画 @font-face设置字体*/
@media screen and (max-width:768px) {
.container {
width:100%;
/*height:1000px;*/
height:1000px;
background-color: blue;
}
}
@media screen and (max-width:992px) and (min-width: 768px) {
.container {
width:750px;
height:1000px;
margin:0 auto;
background-color: green;
}
}
@media screen and (max-width:1200px) and (min-width: 992px) {
.container {
width:970px;
height:1000px;
margin:0 auto;
background-color: red;
}
}
@media screen and (min-width:1200px) {
.container {
width:1170px;
height:1000px;
margin:0 auto;
background-color: yellow;
}
}
</style>

使用bootstrap的基本模板

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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!--文档编码申明-->
<meta charset="utf-8">
<!--要求当前网页使用浏览器最高版本的内核来渲染-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--视口的设置:视口的宽度和设备一致,默认的缩放比例和pc端一致,用户不能自行缩放-->
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=0">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<!-- 优先加载和浏览器解释-->

<title>Bootstrap 101 Template</title>

<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- html5shiv 和 respond 分别用来解决IE8版本浏览器不支持 H5标签和媒体查询的 不兼容问题-->
<!-- HTML5 shiv and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- 警告:不能以file形式打开,本地打开。最好http://打开 -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!-- 在 IE 9 一下引入-->
<!--[if lt IE 9]>
<script src="../lib/html5shiv/html5shiv.min.js"></script>
<script src="../lib/respond/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>你好,世界!</h1>

<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
</body>
</html>

两种重置样式库:reset.css 和 normalize.css

共同点:都是重置样式库,增强浏览器表现一致性

不同点:举个例子->ul
reset.css list-style:none;—根据需求重置掉一些样式

normalize.css 不会重置ul样式—本身已经在每个浏览器表现一致的元素,每个浏览器都有这个点,所以没有重置

一句话:都是为了增强浏览器一致性地,但是normalize不会重置已经一致的元素。

使用bootstrap的栅格系统(12等份)

需求:

大屏设备 lg 均分6等份

中屏设备 md 均分4等份

小屏设备 sm 均分3等份

超小屏设备 xs 均分2 等份

1
2
3
4
5
6
7
8
9
10
<div class="container">
<div class="row">
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6"></div>
</div>
</div>

扩展:偏移offset,往后推push,往前拉pull,比如col-xs-offset-3默认是左偏移3格,col-xs-push-9往后推9格,col-xs-pull-3往前拉3格

响应式工具——bootstrap

需求:

  • 大屏设备 大屏设备显示
  • 中屏设备 中屏设备隐藏
  • 小屏设备 小屏设备显示
  • 超小屏设备 超小屏设备隐藏

原生实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
@media screen and (min-width:1200px) {
.box {
display:block;
}
}
@media screen and (min-width:992px) and (max-width:1200px) {
.box {
display:none;
}
}
@media screen and (min-width:768px) and (max-width:992px) {
.box {
display:block;
}
}
@media screen and (max-width:768px) {
.box {
display:none;
}
}
</style>
<div class="box"></div>

bootstrap实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--
visible-lg 大屏显示,其他隐藏
visible-md 中屏显示,其他隐藏
visible-sm 小屏显示,其他隐藏
visible-xs

3.2版本以后,建议使用hidden https://v3.bootcss.com/css/原文档中提到过

hidden-lg 大屏隐藏 其他显示
hidden-md
hidden-sm
hidden-xs
-->
<div class="box visible-lg visible-sm">内容</div>

媒体查询-扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.container {
width:100%;
height:1000px;
background-color: blue;
}
@media screen and (min-width:768px) {
.container {
width:750px;
background-color: green;
}
}
@media screen and (min-width:992px) {
.container {
width:970px;
background-color: red;
}
}
@media screen and (min-width:1200px) {
.container {
width:1170px;
background-color: orange;
}
}

其实利用的是优先级的原理

before与after的理解

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
<style>
.box {
width:200px;
height:200px;
background-color: pink;
margin:200px auto;
position:relative;
}
.box::before {
position:absolute;
top:10px;
left:10px;
width:20px;
height:20px;
content:"";
background-color: #fff;
border-radius:5px;
display:block;
}
.box::after {
position:absolute;
bottom:10px;
left:10px;
width:20px;
height:20px;
content:"";
background-color: #fff;
border-radius:5px;
display:block;
}
</style>

实际效果:

三、rem布局

认识rem

rem是相对单位

em大小是基于父元素的字体大小

rem r====>root 根的意思,rem大小是基于html的字体大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
html {
font-size:10px;
}
body {
margin:0;
padding:0;
font-size:50px;
line-height:1;
}
.em {
font-size:2em;
}
.rem {
font-size:2rem;
}
</style>
<div class="em">aaa</div>//字体是100px
<div class="rem">aaa</div>//字体是20px

看到上面的例子是不是理解了呢?

各种布局比较

  1. 伸缩布局 flex
  2. 流式布局 百分比
  3. 响应式布局 媒体查询
  4. rem布局 通过控制html上的字体大小去控制页面上所有以rem为单位的基准值控制尺寸
    1. 把px转化为rem
    2. 页面制作的时候,psd上量取的px转成rem使用
    3. 怎么换算?预设一个基准值,方便计算,100px
    4. 适配的时候,设置基准值 320px 50px 怎么算使得(640px 100px == 320px 50px)
    5. 换算公式:当前rem基准值=100/640*320=50

1,2,3的共同点:元素只能做到宽度的适配(图片除外)

rem布局:宽度和高度都能做到适配(等比缩放)

rem搭配less简直完美

阅读量