H5移动端的适配以及在移动端显示的视觉偏差
web.jpeg
1.移动端认知
- 分类
- 原生
- iOS,编写语言OC/swift
- 安卓,编写语言java
- H5 编写的移动端是web网页,简称
M站,使用与手机浏览器,其原理就是通过手机上浏览器通过webKit内核去加载写好的html5和css文件
- 原生
一般大型的公司是这些区分开的,原生人需要,H5的人也是需要,比如电商类,旅游类等
2.开发常用的单位
2.1 像素px
-
不会随着视口大小的变化而变化, 像素是一个固定的单位(绝对单位)
image.png
2.2 百分比%
- 子元素
宽度/高度是参考父元素宽度/高度计算的
.father {
width: 300px;
height: 200px;
background-color: rebeccapurple;
margin: 100px auto;
}
.son {
/*
2.1 子元素宽度是参考父元素宽度计算的
* 2.2子元素高度是参考父元素高度计算的
*/
width: 50%;
height: 50%;
background-color: green;
}
image.png
-
子元素padding无论是水平还是垂直方向都是参考父元素宽度计算的
.father {
width: 300px;
height: 200px;
background-color: rebeccapurple;
margin: 100px auto;
}
.son{
padding-top: 50%;
padding-bottom: 50%;
padding-left: 50%;
padding-right: 50%;
background-color: green;
}
image.png
-
子元素margin无论是水平还是垂直方向都是参考父元素宽度计算的
.father {
width: 300px;
height: 200px;
background-color: rebeccapurple;
margin: 100px auto;
}
.son{
width: 100px;
height: 100px;
margin-top: 50%;
margin-left: 50%;
margin-right: 50%;
margin-bottom: 50%;
background-color: green;
}
image.png
-
不能用百分比设置元素的border
注意:
百分比是一个动态的单位, 会随着父元素宽高的变化而变化(相对单位),如果父元素没有高那么设置子元素为100%也是不起作用的,只能是根据子元素的内容撑起高度
2.3 em单位
-
em是前端开发中的一个动态单位, 是一个相对于元素字体大小的单位- 比如:
font-size: 12px; ,那么1em就等于12px
- 比如:
- 当前元素设置了字体大小, 那么就相对于当前元素的字体大小
- 当前元素
没有设置字体大小, 那么就相当于第一个设置字体大小的祖先元素的字体大小 - 如果
当前元素和所有祖先元素都没有设置大小, 那么就相当于浏览器默认的字体大小
自身元素有 字体大小
.son {
font-size: 13px;
width: 10em;
height: 10em;
background-color: orange;
}
image.png
自身元素没有设置
font-size父元素设置font-size
.father {
font-size: 15px;
}
.son {
width: 10em;
height: 10em;
background-color: orange;
}
image.png
2.4 rem单位
-
rem也是一个动态的单位, 会随着根元素字体大小的变化而变化(相对单位) -
rem只根据html根元素的font-size有关 - 如果
根元素没有设置字体大小, 那么就相对于浏览器默认的字体大小
2.5 vw(Viewport Width)和vh(Viewport Height)相对于视口的宽度和高度
-
vw和vh:是前端开发中的一个动态单位, 是一个相对于网页视口的单位 - 系统会将
视口的宽度和高度分为100份,1vw就占用视口宽度的百分之一, 1vh就占用视口高度的百分之一 -
vw和vh和百分比不同的是, 百分比永远都是以父元素作为参考,而vw和vh永远都是以视口作为参考
3.视口 (移动端必备)
- 视口简单理解就是
可视区域大小我们称之为视口 - 通过
meta设置视口大小, 快捷方式meat:vp + tab 键
<meta name="viewport" content="width=device-width, initial-scale=1.0">
width=device-width设置视口宽度等于设备的宽度
initial-scale=1.0初始缩放比例, 1不缩放
maximum-scale:允许用户缩放到的最大比例
minimum-scale:允许用户缩放到的最小比例
user-scalable:用户是否可以手动缩放
4.移动端的适配
4.1移动端适配一(媒体查询)
@media screen and (min-width: 320px) {
// 需要布局的 CSS 代码
}
//适配375屏幕
@media screen and (min-width: 375px) {
// 需要布局的 CSS 代码
}
@media screen and (min-width: 414px) {
// 需要布局的 CSS 代码
}
调整屏幕宽度的时候
不用刷新页面即可响应式展示
特别适合对移动短和PC维护同一套代码的时候
缺点: 由于移动端和PC端维护同一套代码, 所以代码量比较大,维护不方便
4.1移动端适配二 (rem)
在说明使用
rem适配时,需要先说明一个等比缩放问题,因为在我们开发过程中,UI设计图片一般是750 * xxx的或者1125 * xxx的大小,所以我们需要对设计师提供的图片进行等比缩放, 这样才能1:1还原设计图片
- 如果等比例缩放 ?
如果是 750 * xxx 的图片,我们自己定义一个
平均的分数
比如: 750设计图片分为10份, 那么每一份的大小就是75px
那么在目标手机屏幕上与之对应的分数应该 :
375屏幕也分为10份, 那么每一份的大小就是37.5px,我们可以根据rem把计算出来的结果设置为html的font-size = 37.5px
计算图片的等比例大小
原始元素尺寸 / 原始图片每一份大小 * 目标屏幕每一份大小 = 等比缩放后的尺寸
比如:100 * 100 的图片 等比缩放为:100/75 * 37.5 = 46.667px;
与之对应的rem为100/75 = 1.33rem,1rem= 37.5px
布局适配,不同的时机屏幕对应的
rem的font-size不同
320的屏幕,分10份 对应的事font-size = 32px
375屏幕也分为10份, 那么每一份的大小就是37.5px,
414的屏幕对应的事font-size = 41.4px
750设计图片分为10份, 那么每一份的大小就是75px
所以下面的布局中,只要使用到 距离计算或者宽度和高度计算时 就要换算成对应的rem
<style type="text/less">
*{
padding: 0;
margin: 0;
}
@media screen and (max-width: 320px) {
html{
font-size: 32px;
}
}
@media screen and (min-width: 375px){
html{
font-size: 37.5px;
}
}
@media screen and(min-width:414px ){
html{
font-size: 41.4px;
}
}
.header {
position: relative;
}
.header > img {
width: 100%;
height: auto;
}
.header > p {
position: absolute;
top: 80/75rem;
left: 50%;
transform: translateX(-50%);
color: #fff;
font-size: 36/75rem;
}
.middle,.bottom{
height: 290/75rem;
position: relative;
}
.main {
border: 1px dashed #0d7efb;
border-radius: 5/75rem;
padding: 10/75rem;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.main > img:nth-of-type(1){
width: 410/75rem;
height: 270/75rem;
vertical-align: bottom;
}
.main > img:nth-of-type(2){
position: absolute;
top: 60/75rem;
left: 50%;
transform: translateX(-50%);
width: 84/75rem;
height: 84/75rem;
}
.bottom {
margin-top: 35/75rem;
}
</style>
改进(视觉偏差 和 动态的计算rem对应的font-size)
在真实的开发中,由于不同的屏幕对应的
像素不太一样,我们在设置CSS中对应的是虚拟像素(对应下图的逻辑分辨率)和手机上真实的物理像素(对应下图的 分辨率)时,有时存在偏差,
所谓的偏差就是,CSS的虚拟像素在显示在真实手机上时,由于真实手机的分辨率可能是CSS虚拟像素的2倍或者3倍,那么对应出来的布局可能就是css 1px在真实手机上可能就是4px 和 9px,因为2/3倍 扩大至x,y轴上的像素网格点
iPhone各屏幕分辨率.jpg
为了解决上述问题的
视觉偏差,那么对应的视口就要进行相应的缩放
- 那么
如何获取到对应的缩放比例呢?
通过
window.devicePixelRatio获取当前的设备像素
测试:在不同的模拟器上打印出的window.devicePixelRatio是不同的,iphone对应的就是上图的Scale里面的 数字
因为圆视口对应的事真实initial-scale= 1.0,所以我们通过通过<meta name="viewport">的initial-scale属性来进行 缩小,从而来解决视觉偏差
//获取不同手机上 进行缩放的比例
let scale = 1.0 / window.devicePixelRatio;
//模板字符串
let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
//写入document对象
document.write(text);
动态的计算rem对应的font-size
因为没有个对应的手机的真实内容的
可见宽度是固定的,所以在加载的时候
根据屏幕的宽度设置自己的定义的 份数 就是 对应的font-size,比如上述自己定义的是 10份
document.documentElement.style.fontSize = window.innerWidth / 10+ "px";
所以上述代码的 完美适配方式为
<script type="text/javascript">
// 获取不同手机上 进行缩放的比例
let scale = 1.0 / window.devicePixelRatio;
//设置模板字符串
let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
//写入document对象
document.write(text);
//动态设置 fontSize
document.documentElement.style.fontSize = window.innerWidth / 10 + "px";
</script>
对应上述代码的
CSS设置,删除@media对应的媒体适配