响应尺寸
viewport
移动端浏览器将网页放置在虚拟的viewport中,不同手机分辨率对视口进行缩放即可全屏显示内容。不同浏览器定义的viewport尺寸不同。
# 视口概念
所以viewport也可以理解为屏幕有多少像素来显示内容,这和电脑端是不同的。
- 电脑端是显示器的多大分辨率多少就用多少像素来显示
- 移动端是viewport分辨率多少就用多少像素来显示
- viewport是可以改变的,就像显示器的分辨率可以改变一样

# 查看尺寸
主流浏览器的默认viewport大小(因为浏览器间不统一,所以也没有必要关注下面的尺寸,只做为了解就行)
| 浏览器 | 尺寸 |
|---|---|
| Safari iPhone | 980px |
| Opera | 850px |
| Android WebKit | 800px |
| IE | 974px |
可以在控制台查看到 viewport大小
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
后盾人十年来我们录制了大量制作精良的课程,并且依然在不段迭代更新中,首先感谢老朋友们十年来的支持,也欢迎新朋友们观看我们的视频教程。
</body>
</html>
在浏览器打开上面网页,并通过控制台查看结果如下

# 改变视口
使用<meta name="viewport" content="width=2000px" />可以调整视口,这有点像设置相同尺寸桌面显示不同的分辨率。
下面是将视口定义为2000与300的差别,这类似于同样27寸分辨率下4K与1080显示的区别。

# 媒体查询
@media是根据分辨率来响应式布局的,所以viewport尺寸的不同将影响媒体查询的使用。
下面代码用于在分辨率小于500px时更改内容颜色,但是因为没有设置viewport,而使用浏览器默认的视口,这会造成在手机上无法进行响应操作,因为viewport尺寸大于500px。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<style>
@media (max-width: 500px) {
body {
color: red;
}
}
</style>
后盾人十年来我们录制了大量制作精良的课程,并且依然在不段迭代更新中,首先感谢老朋友们十年来的支持,也欢迎新朋友们观看我们的视频教程。
</body>
</html>
面当我们设置好viewport后就可以进行响应处理了,下面是将viewport设置为500px
<meta name="viewport" content="width=500"/>

# 设备尺寸
像上面通过人为设置像素值,显示是不可取的。如果响应布局当然希望viewport与设备尺寸一至,可喜的是,系统为我们提供了device-width变量值用于识别设备宽度。
<meta name="viewport" content="width=device-width" />
# 其他属性
下面介绍其他可用在meta标签上的属性
| 属性 | 说明 |
|---|---|
| initial-scale=1 | 初始缩放比例 |
| minimum-scale=.5 | 允许用户最小缩放比例 |
| _maximum-scale_=2.5 | 允许用户最大缩放比例 |
| user-scalable=yes | 是否允许用户绽放 |
mac用户在 chrome中使用option+shift+鼠标按住移动进行缩放
# JS延迟
设置 user-scalable=no 时可以js解决300延迟的问题,你也可以理解为当设置 user-scalable=yes 时,系统要识别两只手指,所以要有个宽容时间。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes" />
</head>
<body>
<style>
body {
width: 100vw;
height: 100vh;
}
</style>
<script>
let i = 1
document.body.addEventListener('click', () => console.log(i++))
</script>
</body>
</html>
# rem/em
em理解为继承(相对)单位,它需要一个参考的继承属性。
# em
我们知道字体大小是可以继承的,我们对下面例子进行说明
- span没有设置字体大小,将继续父级article标签定义的大小15px
- strong定义了2em字体大小,因为使用了em单位即是父级15px X 2=30px
可以通过edge或chrome浏览器调试工具的已计算标签查看
<style>
article {
font-size: 15px;
}
strong {
font-size: 2em;
}
</style>
<article>
<span>houdunren.com</span>
<strong>后盾人</strong>
</article>
# 多级继承
下面代码是多层次的嵌套,如果使用em单位定义font-size会向上一直查找定义了font-size的父级来进行计算。直到找到html标签为止。
所以下面的strong定义的2em计算结果依然是30px即 article标签的font-size:15px 乘以2。
<style>
article {
font-size: 15px;
}
strong {
font-size: 2em;
}
</style>
<article>
<div>
<span>houdunren.com</span>
<strong>后盾人</strong>
</div>
</article>
# padding/margin
font-size本身是可以继承的,所以em参考父级元素定义的font-size。但padding/margin在CSS中不会继承父级定义的padding/margin。
如果padding/margin使用em单位将参考本元素的font-size。
下面示例中最终strong标签的padding与margin都是60px,因为定义了2em所以最终结果为当前标签的font-size*2
<style>
article {
font-size: 15px;
}
strong {
font-size: 2em;
padding: 2em;
margin: 2em;
}
</style>
<article>
<div>
<span>houdunren.com</span>
<strong>后盾人</strong>
</div>
</article>
# rem
rem本向也有em的特性即参考继承,只不过它只参考根元素(root)即html标签定义的font-size。我们来通过下面的示例详细说明。
- 为html标签定义了font-size:30px,页面中使用rem单位的元素将30px为参考,即1rem=30px
- span标签使用了font-size:2em,会参考父级article定义的font-size,最后计算结果为font-size:30px
- strong标签定义了font-size:2rem,会参考html标签的font-size,最后计算结果为60px
- strong标签定义了padding:2rem,计算结果也是60px
- strong标签定义了margin:2em,将会参考本身元素的font-size,上面已经说明strong的font-size为60px,所以最终margin结果为120px
<style>
html {
font-size: 30px;
}
article {
font-size: 15px;
}
span {
font-size: 2em;
}
strong {
display: block;
font-size: 2rem;
padding: 2rem;
margin: 2em;
}
</style>
<article>
<div>
<span>houdunren.com</span>
<strong>后盾人</strong>
</div>
</article>
# 使用建议
em与rem都是不错的响应单位,根据需要进行选择。em具有继承特性,rem的参考元素是唯一HTML,所以rem操作简单。em继承关系会相对复杂。
布局上的margin/padding使用rem是不错的选择,字体大小等使用em与rem都可以。
# 尺寸响应
# 问题分析
下面是尺寸为375x600的设计稿,绿色区域为200px红色为175px宽度

使用固定像素定义时在iphone6与iphon6 plus中的显示效果并不相同

实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" />
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
<style>
div {
height: 600px;
}
.left {
width: 200px;
background: #76ba65;
float: left;
}
.right {
width: 175px;
background: #df0f71;
float: left;
}
</style>
</html>
# 自动响应
实际操作中不同设备只能取宽或高一个尺寸为响应处理,一般情况下我们取宽度响应,高度自动处理。小尺寸时高度产生垂直滚动条,这并不影响什么。
计算公式
使用rem单位来处理响应,因为改变rem单位会影响所有使用rem的元素,这确实非常的方便。
- rem是在根元素中定义的font-size
- rem用来在多个设备响应处理时使用
- html元素也可以使用:root选择器选择
下面展示的设计稿为375px宽,下面公式表示1px所占的屏幕尺寸宽度,有以下几点需要说明
- 100vw表示100%视口宽度
- 因为使用了vw宽度系统会根据不同设备自动计算rem
:root {
font-size: calc(100vw / 375);
}
完整代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>houdunren.com</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" />
</head>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
<style>
:root {
font-size: calc(100vw / 375);
}
div {
height: 600rem;
}
.left {
width: 200rem;
background: #76ba65;
float: left;
}
.right {
width: 175px;
background: #df0f71;
float: left;
}
</style>
</html>
现在使用不同设备时宽度已经自动可以响应设置了