导读
我的项目是基于设计稿750px,vue-cli3+sass搭建的(且sass-loader版本是8,为什么要说这个呢,因为后面会通过vue.config.js引用全局scss文件,如果sass-loader版本是7或者vue-cli是2的话,引用的配置是不一样的,不注意这个的话会有坑);
移动端适配会写,但原理有时却不清晰,最近参考了上面的链接,深受启发,那么web移动端开发中,如何让UI图完美适配?要弄清原理,首先需要理解一些相关概念
一、英寸
换算:1英寸=2.54厘米
一般手机尺寸(屏幕对角线长度)单位都是英寸表示的
二、分辨率和像素
2.1 >> 像素
为影像显示的基本单位,译自英文“pixel”,pix是英语单词picture的常用简写,加上英语单词“元素”element,就得到pixel,故“像素”表示“画像元素”之意,有时亦被称为pel(picture
element)。每个这样的消息元素不是一个点或者一个方块,而是一个抽象的取样。仔细处理的话,一幅影像中的像素可以在任何尺度上看起来都不像分离的点或者方块;但是在很多情况下,它们采用点或者方块显示。每个像素可有各自的颜色值,可采三原色显示,因而又分成红、绿、蓝三种子像素(RGB色域),或者青、品红、黄和黑(CMYK色域,印刷行业以及打印机中常见)。照片是一个个取样点的集合,在影像没有经过不正确的/有损的压缩或相机镜头合适的前提下,单位面积内的像素越多代表分辨率越高,所显示的影像就会接近于真实物体。
简单理解像素即一个小方块,它具有特定的位置和颜色。
2.2 >> 分辨率
对电脑显示器等,分辨率是用像素数目衡量;对数字文件印刷,分辨率是通常用每英寸所含点或像素〔dpi〕来衡量
iPhone XSMax和 iPhone SE的分辨率分别为 2688x1242和 1136x640。这表示手机分别在垂直和水平上所具有的像素点数。
2.3 >> PPI
像素密度(pixel density)单位,即每英寸的长度中所具有的像素
三、设备独立像素
实际上,上面我们描述的像素都是物理像素,即设备上真实的物理单元。
下面我们来看看 设备独立像素究竟是如何产生的:
随着智能手机的快速发展,相同尺寸的手机,其分辨率却高出了许多,比如下图中,左边黑色手机分辨率是640×960,右边白色手机分辨率是320×480。
理论上,同样大小的图片和文字在黑色手机上会被缩放一倍。但这样的话,随着分辨率的提高,页面元素不就越来越小了么,这怎么能行呢!
然而,事实并不是这样的,我们现在使用的智能手机,不管分辨率多高,他们所展示的界面比例都是基本类似的。乔布斯在 iPhone4的发布会上首次提出了 RetinaDisplay(视网膜屏幕)的概念,它正是解决了上面的问题,这也使它成为一款跨时代的手机。
在 iPhone4使用的视网膜屏幕中,把 2x2个像素当 1个像素使用,这样让屏幕看起来更精致,但是元素的大小却不会改变
如果黑色手机使用了视网膜屏幕的技术,那么显示结果应该是下面的情况,比如列表的宽度为 300个像素,那么在一条水平线上,白色手机会用 300个物理像素去渲染它,而黑色手机实际上会用 600个物理像素去渲染它。
我们必须用一种单位来同时告诉不同分辨率的手机,它们在界面上显示元素的大小是多少,这个单位就是设备独立像素( DeviceIndependentPixels)简称 DIP或 DP。 上面我们说,列表的宽度为 300个像素,实际上我们可以说:列表的宽度为 300个设备独立像素。
打开 chrome的开发者工具,我们可以模拟各个手机型号的显示情况,每种型号上面会显示一个尺寸,比如 iPhone X显示的尺寸是 375x812,实际 iPhone X的分辨率会比这高很多,这里显示的就是设备独立像素。
3.1 设备像素比
设备像素比 device pixel ratio简称 dpr,即物理像素和设备独立像素的比值
四、视口
视口( viewport)代表当前可见的计算机图形区域。在 Web浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的 UI, 菜单栏等——即指你正在浏览的文档的那一部分。
一般我们所说的视口共包括三种:布局视口、视觉视口和理想视口,它们在屏幕适配中起着非常重要的作用。具体内容可参考顶部连接(原内容太多)。
总结:为了适配所有机型,且在移动端让页面获得更好的显示效果
- 我们必须让布局视口、视觉视口都尽可能等于理想视口,即三口合一
- 我们在写样式时需要把设计稿的物理像素转换为设备独立像素,WEB端开发,在写 CSS时,我们用到最多的单位是 px,即 CSS像素,当页面缩放比例为 100%时, 1个CSS像素=1个设备独立像素
- 通过动态设置rem的值,再配合global.scss中定义的函数px2rem(),实现适配
附上代码:
index.html中
<!-- 三口合一,缩放比例为1,禁止用户放大缩小页面,保证1px为1个设备独立像素 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<script>
// 动态设置font-size
function initRootFontSize(){
// 相当于1rem=设备屏幕1/10宽
document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
}
document.addEventListener("DOMContentLoaded",function(){
initRootFontSize()
},false)
window.onresize = initRootFontSize
在src/common/styles/global.scss文件中,使用sass自定义函数px2rem()
html,
body {
margin: 0;
padding: 0;
}
body{
font-size: 14px;
}
// 将设计稿的 px 转 rem
@function px2rem($args) {
@return $args/75 * 1rem;
}
通过配置vue.config.js,引用这个全局的global.scss文件,详情请看vue官方说明,值得一说的是,如果你的sass-loader版本是^7的,请用data,而我的版本是 ^8,所以用prependData
module.exports = {
lintOnSave: false,
css: {
loaderOptions: {
sass: {
prependData: `
@import "@/common/styles/global.scss";
`
}
}
},
}
此时就可以快乐的 通过px2rem(设计稿物理尺寸) 写尺寸咯,如下所示:
<template>
<div class="home">dd</div>
</template>
<script>
export default {
name: "home"
};
</script>
<style lang="scss">
// 设计稿上这个div的尺寸为375*180
.home {
height: px2rem(180);
background: rgb(223, 174, 174);
width: px2rem(375);
}
</style>
如果这样还不行,请重新npm run serve,并刷新你的网页