谁有一颗玲珑剔透的心,他就会知道何时心碎。
foreword
这篇总结了我个人所知道的一些关于移动端适配的知识。希望对读者有所帮助。
start
(1) appetizers(开胃知识点)
因为这一节基础知识以及概念性内容多,有一定前端基础的可以略过这一节。(该知识点文字来源于网络资料)
①屏幕尺寸、屏幕分辨率、屏幕像素密度
屏幕尺寸:指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米,常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等。所以6.0的手机 6*2.54 = 15.24 厘米。
屏幕分辨率:指在横纵向上的像素点数,单位是px,1px=1个像素点。一般纵向像素 * 横向像素来表示一个手机的分辨率,如1960*1080。(这里的1像素指的是物理设备的1个像素点)。比如(iphone6 750 * 1337) (iphone6plus 1960 * 1080)
屏幕像素密度/像素密度/屏幕密度::屏幕上每英寸可以显示的像素点的数量,单位是ppi,即“pixels per inch”的缩写。屏幕像素密度与屏幕分辨率有关。
②物理像素,CSS像素
设备像素/物理像素:(分辨率)买手机的时候有一个n x m的分辨率,那是屏幕的n x m个呈像的点,一个点(小方格)为一个物理像素。它是屏幕能显示的最小粒度。设备像素也被称为物理像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。任何设备的物理像素的数量都是固定的。
CSS像素:CSS像素是一个抽象的单位,主要使用在浏览器上,用来精确的度量(确定)Web页面上的内容。它是为web开发者创造的,在CSS或者JavaScript中使用的一个抽象的层。一般情况下,CSS像素被称为与设备无关的像素(device-independent像素),简称为“DIPs”。在一个标准的显示密度下(普通屏),一个CSS像素对应着一个设备像素。
CSS像素与物理像素的关系:一个width为200px的元素,它占据了200个CSS像素,但200个CSS像素占据多少个物理像素取决于屏幕的特性(是否是高密度,即像素比)和用户的缩放行为。在苹果的视网膜屏幕中,视网膜的像素密度是普通屏幕的两倍,这个元素就跨越了400个设备像素,如果用户放大,它将跨越更多的设备像素。当然现在好多手机的像素比变得越来越大,比如我之前用的魅族手机和现在用的iphone 8 plus都已经达到了3,所以这个元素正常情况下就跨越了600个设备像素。
设备独立像素:设备独立像素(也叫密度无关像素),可以认为是计算机坐标系中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如:CSS像素),然后由相关系统转换为物理像素。
位图像素:一个位图像素是栅格图像(如:png,jpg,gif等)最小的数据单元,至少1个位图像素对应1个物理像素,图片才能得到完美清晰的展示。
对于Web开发者而言:我们使用的每一个CSS和JavaScript定义的像素本质上代表的都是CSS像素,我们在开发过程中并不在意一个CSS像素到底跨越了多少个设备像素。我们将这个依赖于屏幕特性和用户缩放程度的复杂计算交给了浏览器。
③像素比
像素比:它的官方的定义为:设备物理像素和设备独立像素的比例,也就是devicePixelRatio = 物理像素/独立像素(window.devicePixelRatio)
console.log(window.devicePixelRatio)
④视口
布局视口:在PC端上,布局视口等于浏览器窗口的宽度。
console.log(document.documentElement.clientWidth);//布局视口
视觉视口:视觉视口是用户正在看到的区域。用户可以缩放来操作视觉视口,而不影响视觉视口的宽度。视觉视口决定了用户看到了什么。在JavaScript上获取视觉视口的宽度可以通过`window.innerWidth得到。
console.log(innerWidth);//视觉视口,设置滚动条包括滚动条
以及可以用js求得。
console.log(outerWidth);//包括浏览器的镶边区域
console.log(screen.width);//屏幕宽度
(2)实战引入一(以rem为基础单位)
rem: ‘The font size of the root element’ 就是以根元素的字体大小为单位。rem适配的原理就是以html的font-size大小为单位来布局。
- 2.1 使用@media查询设置rem:
//代码
html{
max-width: 640px;
margin: 0px auto;
font-size: 100px;
}
@media only screen and (max-width: 414px){
html{
font-size: 64px;
}
}
@media only screen and (max-width: 375px){
html{
font-size: 58px;
}
}
@media only screen and (max-width: 360px){
html{
font-size: 56px;
}
}
@media only screen and (max-width: 320px){
html{
font-size: 50px;
}
}
//不要忘记在head标签中添加如下视口设置
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
设计师给我们的设计图纸一般宽度为640,750,375.这里以640 为基准。整个屏幕的宽度设置为
640/100 = 6.4rem 414/64 ≈ 6.4rem 375/58 ≈ 6.4rem 360/56 ≈ 6.4rem 320/50 ≈ 6.4rem
这里只是列举了几个常用的@media查询,当具体如果应用面更广大,需要更多的查询,方法也是迥异。
通过这个适配,我们可以在写CSS的时候使用rem作为单位,1rem = 100px。这种方法也是一种比较常用的方法。
缺点:这种方法需要计算量,需要通过给出的范围内,计算出相应的font-size,以及找出每个范围内最合适的font-size会比较麻烦。也存在一定的误差。
- 2.2 使用js获取innerWidth 或者 clientWidht 设置font-size
//代码
document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
//或者
document.documentElement.style.fontSize = window.innerWidth/6.4 + 'px';
//通过以上设置 就相当于把整个屏幕的宽度设置为 6.4rem ,而根据设计图是640px的,就可以相当于
//100px = 1rem ,在布局的时候就可以用rem为单位布局,(设计图是其他大小就改为多少)
//可以添加代码
document.body.style.fontSize = '14px'; // 在body上将字体还原大小,避免页面无样式字体超大
//不要忘记在head标签中添加如下视口设置
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
当然如果你在电脑上访问移动端网页的时候。也就是document.documentElement.clientWidth>640的时候,如果你还想更好的访问。
//可以添加代码
var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640){
deviceWidth = 640;document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';
}
- 2.3 1px边框特殊处理
这里的1px是指的是1物理像素,当有特殊需求的时候,比如说边框需要1物理像素的。meta标签中的initial-scale属性设置缩小效果,设置好meta标签后,我们可以动态修改它。
//代码
//不要忘记在head标签中添加meta标签
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
let dpr = window.devicePixelRatio; //求出像素比
let scale = 1/dpr; //求出缩放比例
let width = document.documentElement.clientWidth/6.4 * dpr; //乘以像素比,rem可以正常使用
let metaN = document.querySelector('meta[name="viewport"]');
metaN.setAttribute('content','content','initial-scale=' + scale + ', maximum-scale=' + scale + ',
minimum-scale=' + scale + ', user-scalable=no'); //设置缩放
let styleN = document.createElement('style');
styleN.innerHTML = 'html{ font-size:' + width + 'px; }'; //设置rem
document.head.appendChild(styleN);
- 2.4 页面中字体使用font-size
这里淘宝和网易页面中字体font-size都不使用rem,而是使用@media查询,这个仅供参考,因为使用rem也是可以的。
//代码
@media screen and (max-width:321px){.test{font-size:15px} }
@media screen and (min-width:321px) and (max-width:400px){ .test{font-size:16px}}
@media screen and (min-width:400px){.test{font-size:18px} }
(3)实战引入二(以vw wh为基础单位)
vw vh 可以轻松搞定弹性布局,
1vw = 1/100th viewport width
1vh = 1/100th viewport heght
用viewport width的百分比来设置element width
其中vmin相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin。
其中vmax相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax。
通过vmin 和 vmax 可以做 移动端手机旋转的样式。
缺点/优点:vw vh vmin vmax 对移动端手机兼容性并不是很强,要求Android 4.4 以上的版本,虽然现在不是特别普及,但是现在Android 4.4 版本的使用用户已经凤毛麟角了,所以使用 vw 为适配单位很有可能成为热门。
在移动端 iOS 8 以上以及 Android 4.4 以上获得支持,并且在微信 x5 内核中也得到完美的全面支持。
以vw作为布局单位,方法如下。(使用sass函数编译 )
//640px作为设计稿基准
$vm_base: 640;
@function vm($px) {
@return ($px / 640) * 100vw;
}
//通过代码,假如设计稿中元素的宽度是 40px ,那么就可以在样式中写
.test{
width:vm(40)
}
如果对你有帮助,请动动小手点个赞吧。
<完结-待补充>