1、相关概念
在学习移动端之前,我们先来学习—些基础的概念和专有名词,这些知识会帮助我们更深刻理解移动端适配。
1.1、屏幕相关
1.1.1、屏幕大小
屏幕大小指屏幕主对角线长度,单位是英寸(inch)。常见的尺寸有:4.7寸、5.0寸、5.5寸、6.1寸等等。至于说为什么不用宽高来表示屏幕大小,这是因为国外最早的手机厂商就没用宽高来表示,英寸也是国外常见的长度单位。
1.1.2、屏幕分辨率
分辨率是指屏幕在 横向、纵向上所拥有的物理像素点总数。一般用x * y表示。 例如iphone13pro的屏幕分辨率为2532 x 1170
- 注意点: 屏幕分辨率是一个固定值,当屏幕被生产出来时就已经固定了!
1.2、像素相关
1.2.1、物理像素
又称:设备像素物理像素是一个长度单位,单位是px,1个物理像素就是屏幕上的一个物理成像点,就是屏幕中一个微小的发光物理元器件(可简单理解为超级微小的发光灯泡),是屏幕能显示的最小粒度。它由屏幕制造商决定,屏幕生产后无法修改。例如iPhone 6的横向上拥有的物理像素为750、纵向上拥有的物理像素为1334,我们也可以用:750*1334表示。
不管像素长什么样。它一定是由red、green、blue这三种颜色组成
1.2.2、css像素
又称:逻辑像素,单位也是px,它是为Web开发者创造的,用来精确的度量Web页面上的内容大小。我们在编写css、js、less(css预编译器)中所使用的都是css像素(可以理解为:“程序员像素")
思考∶我代码中所写的1px (css像素),到了屏幕上到底对应几个物理像素呢?是1个css像素就对应1个物理像素(“发光的灯泡")吗?要探讨这个对应关系,就要学习接下来的新概念∶设备独立像素。
1.2.3、设备独立像素
设备独立像素简称DP (device-independent pixel),又称:屏幕密度无关像素。
- 在没出现【高清屏】的年代,1个css像素对应1个物理像素,但自从【高清屏】问世,二者就不再是1对1的关系了。苹果公司在2010年推出了一种新的显示标准:在屏幕尺寸不变的前提下,把更多的物理像素点压缩至一块屏幕里,这样分辨率就会更高,显示效果就会更佳细腻。苹果将这种屏幕称为:Retina display(又名:视网膜屏幕),与此同时推出了配备这种屏幕的划时代数码产品——iPhone4。
这张图是发布会现场的概念图,我们可以看到两个大小相等的盒子,里面的方块就表示着像素,左边的像素块很明显大于右边的像素块,同样大小的一块区域,由更多的像素点呈现,画面就会更加精致
但同样尺寸的屏幕压入更多的像素,那么像素的大小自然要发生变化,同样是css代码中2x2的盒子,iphone3的盒子要大于iphone4的盒子,那么怎么实现呈现在我们面前大小相等的效果的呢?设备独立像素应运而生。我们代码中写的css像素会转换为设备独立像素,而设备独立像素又会转换为屏幕上的物理像素。
css像素与设备独立像素之间的关系
- 在无缩放的情况下,1css像素等于1设备独立像素 设备独立像素与物理像素之间的关系
- 普通屏幕下1个设备独立像素等于1个物理像素
- 高清屏幕下1个设备独立像素等于N(N>1)个物理像素
1.2.4、设备像素比(dpr)
像素比(dpr): 单一方向上设备【物理像素】和【设备独立像素】的比例。即: dpr=物理像素/设备独立像素,在浏览器中用window.devicePixelRatio获取,在css中用device-pixel-ratio。
几款手机的屏幕像素参数,点击查看更多
1.2.5、像素之间的关系
在不考虑缩放的情况下
- 普通屏(dpr=1):1css像素 = 1设备独立像素 = 1物理像素
- 高清屏(dpr=2):1css像素 = 1设备独立像素 = 2物理像素
- 普通屏(dpr=3):1css像素 = 1设备独立像素 = 3物理像素
1.3、视口相关
1.3.1、布局视口
布局视口可以理解为文档对象的逻辑尺寸,单位为逻辑像素(CSS像素)。pc端布局视口一般都为:960px ~1024px这个范围。而这个范围也是版心的位置,浏览器厂商针对移动端设备设计了一个容器,先用这个容器去盛装pc端的网页,这容器的宽度一般是980px,不同的设备可能有所差异,但相差并不大;随后将这个容器等比例压缩到与手机等宽,这是早期将PC端网页移植到移动端的办法。可以通过document.documentElement.clientWidth来获取布局视口的大小
1.3.2、视觉视口
视觉视口就是用户可见的区域,它的绝对宽度永远和设备屏幕一样宽,但是这个宽度里所包含的css像素值是变化的,例如:一般手机会将980个css像素(即布局视口这个容器)压缩放入视觉视口中,而ipad Pro会将1024个css像素放入视觉视口中。移动端获取视觉视口方式: window.innerwidth,不过在Android2、Opera mini、UC8中无法正确获取。
1.3.3、理想视口
与屏幕(设备独立像素)等宽的布局视口,称之为理想视口,所以也可以说理想视口是一种标准:让布局视口宽度与屏幕等宽(设备独立像素),靠meta标签实现。
理想视口的特点:
- 布局视口和屏幕等宽,以iPhone6为例,符合理想视口标准之后:设备独立像素:375px,布局视口宽度:375px。
- 用户不需要缩放、滚动就能看到网站的全部内容。
- 要为移动端设备单独设计—个移动端网站。
设置理想视口的具体方法:
<meta name="viewport" content="width=device-width">
1.3.4、缩放
- PC端 放大时:视口变小,那么就相当于可见范围变少,但为了视口占满我们的屏幕,会等比例放大视口,那么里面的内容也被随之放大
缩小时:视口变大,那么就相当于可见范围变少,但为了视口占满我们的屏幕,会等比例缩小视口,那么里面的内容也被随之缩小
- 移动端 放大时:布局视口不变,视觉视口变小
缩小时:布局视口不变,视觉视口放大
⭐所以移动端缩放屏幕时,并不会改变布局
2、适配
2.1、为什么需要适配
由于移动端设备的屏幕尺寸大小不一,会出现:同一个元素,在两个不同的手机上显示效果不一样(比例不同)。要想让同一个元素在不同设备上,显示效果一样,就需要适配,无论采用何种适配方式,中心原则永远是:等比!。
2.2、适配方案
2.2.1、rem
rem是css中的长度单位,且rem是相对于根元素的字体大小。rem适配的原理:编写时统一以rem为单位,在不同设备上动态调正字体大小
具体方案:
- 方案一(淘宝、百度方案)
1、通过js设置根字体大小:(当前设备横向独立像素值 X 100) / 设计稿宽度
2、编写样式时,直接以rem为单位,值为:设计值 / 100
3、增加js代码进行实时适配
以上图为例,以iphone6为基准,它的设备独立像素(设计稿宽度)为375px,我们将根元素的字体大小设为100px(方便计算),那么就有1rem=100px。我们需要一个在这个设备独立像素下的345px的盒子,以rem为单位的话,就是345px/100px=3.45rem,转换到其他设备3.45rem不变,只需要改变rem的值,因为ihone6的设备宽度除以ihone6plus的设备宽度的值与ihone6的rem值除以ihone6plus的rem值互成比例,那么ihone6plus的rem值就为 (当前设备横向独立像素值 X 基准设备横向独立像素100px) / 设计稿宽度
可以通过一段js代码来动态设置根字体大小
const adaptor = () => {
// 获取布局视口宽度
const dp = document.documentElement.clientWidth
// 计算得到当前设备的根字体大小
const rootFontSize = (dp * 100) / 375
document.documentElement.style.fontSize = rootFontSize + 'px'
}
adaptor()
window.addEventListener('resize',adaptor)
345px的盒子的也应写成3.45rem,这样就实现了rem适配
- 方案二(搜狐、唯品会方案)
方案二与方案一的不同之处在于rem设为 设备横向独立像素 / 10,以ihone6为设计稿,那么
1rem=37.5px,345px的盒子转换为rem单位为 345px / 37.5px = 9.2rem。动态控制根字体大小的js代码如下
const adaptor = () => {
const dp = document.documentElement.clientWidth
const rootFontSize = dp / 10
document.documentElement.style.fontSize = rootFontSize + 'px'
}
adaptor()
window.addEventListener('resize',adaptor)
你肯定会好奇,这个方案写样式时计算特别麻烦,设计稿宽度/37.5无法心算出来,难不成还需要每次都拿计算器出来?这个方案二有存在的必要吗?这是因为方案一的rem值特别大,我们设置字体或者其他样式时,特别不方便,而方案二的rem值较为适合,而且我们还可以引入css预编译器设置css变量,那么我们写样式时只需要用设计稿的大小与这个变量运算即可。 这里以less为例:
/* index.html */
<div className="wrapper">
</div>
/* index.less */
@basic:375/10rem;
`/* 新版less运算一定要带括号 */`
.wrapper {
width: (345/@basic);
height: (150/@basic);
margin: 0 auto;
margin-top: (15/@basic);
background-color: lightblue;
}
2.2.2、vw适配
vw全称viewport width,是视觉视口的宽度等分为100份之后的大小。这个单位就相当于rem适配原理中将视窗划分为100的情况,相比较rem适配方案的优点是省去了处理rem的步骤。缺点是兼容性较差,不过现在兼容性都没什么大问题了
现在我们来看看如何使用vw适配:
也是用rem适配中的例子,以iphone6为基准,设备独立像素为375px,那么1vw=3.75px。345px的盒子转为vw单位345 / 3.75 = 92vw,计算的步骤也可以交给css预编译器来进行。不同设备横向独立像素不同,vw值自然也不同,所以会很方便的完成等比例缩放。
⭐使用vw适配不需要js代码,减少了css和js的耦合度,vw适配也是未来的趋势。