了解像素相关知识:
移动端适配掌握web开发基础系列--物理像素、逻辑像素、css像素
为什么给750px的设计图?
其实我一直很想写一些关于适配方面的文章,因为很多东西只有实践才能对这个知识点更加的了解,而不是查几篇文章就行了~
我希望能够解答这些问题:
1.什么是物理像素,和逻辑像素,DPR 2.为什么我们的设计师给的尺寸都是750px 3.rem适配原理以及对应的插件 4.vw,vh适配原理以及对应的插件
1.什么是物理像素,和逻辑像素,DPR
物理像素(physical pixel, 也叫做设备像素):显示器上的像素,机器生产出来时就已经确定了。 逻辑像素(density-independent pixel也叫做css像素/设备独立像素):用于控制元素样式的样式单位像素,CSS像素从来都只是一个相对值。
物理像素(physical pixel):设备屏幕实际拥有的像素点,屏幕的基本单元,是有实体的。比如iPhone 6的屏幕在宽度方向有750个像素点,高度方向有1334个像素点,所有iPhone 6 总共有750*1334个像素点。
逻辑像素/独立像素(density-independent pixel):我们平时描述一张图片宽高时一般用 200px * 100px,这里的px也是逻辑像素。
我们应该知道iphone6的宽度是375px,这里指的是逻辑像素,那就说明1px的css像素里面包含了2个物理像素点,如果你不怕瞎的话,可以将眼睛靠近电脑屏幕,发现屏幕的界面都是根据红、绿、蓝三个颜色组成
以前的的屏幕是假设是375px的物理像素,对应的是375个物理像素点,其实在很久以前,CSS里写个1px,屏幕就给你渲染成1个实际的像素点,DPR=1,多么简单自然~ 后来苹果公司为其产品mac、iPhone以及iPad的屏幕配置了Retina高清屏,也就是说这种屏幕拥有的物理像素点数比非高清屏多4倍甚至更多。如果还按照DPR=1进行展示,那么同一张图片在高清屏上面显示的区域面积会是非高清屏的1/4,这样的话由于图片在屏幕上的展示面积大大缩小,也会导致出现“看不清”的问题。
在1px对应多个物理像素点主要是为了更加高清,也就是越多,对于我们肉眼能看到红、绿、蓝三个色的难度越大。所以当你使用750px的设计图的时候,对应的图应该是xx2@png
设备像素比(Device Pixel Ratio,DPR)
DPR = 物理像素/逻辑像素
2.rem 适配
2.1 CSS3 长度单位 rem
<meta http-equiv="X-UA-Compatible" cnotallow="IE=edge"> <meta name="viewport" cnotallow="width=device-width, initial-scale=1.0"> <title>Document</title> 我是根元素html的大小 <div>我是两倍</div> <div>我是三倍</div> <style> html{ font-size:12px; } .two { font-size:2rem; height: 5rem; width: 5rem; background-color: red; } .three{ font-size:3rem; height: 10rem; width: 10rem; background-color: yellow; } </style> </head> </html>
比如上面这个例子,虽然我只设置了font-size:12px;,并没有去设置width是多少,但是rem就是看html的font-size的值为固定值,在这个基础上去乘以对应的倍数,其实我这块我以前老是转不过弯,为啥这么多属性就只设置一个font-size的默认值就行,主要还是看rem初始的定义,也许这个属性不是font-size,也许是test等等,他规定什么属性就是什么属性,我是这么理解的,但是font-size的默认值和最小值值得注意
font-size:2rem; => font-size:2*12px;
那么,思考一下,这个html的font-size的值我到底设置多少呢?是不是应该根据视觉宽度来设定
2.2 浏览器默认字体大小
浏览器默认最小字体12px,意思就是我设置一个字体为2px,这个2px,是不会起作用的,会显示城最小的字体12px,默认的字体大小是16px,意思就是假设我不会html做任何设置,对其他的样式class设置2rem,那么显示出来的样式应该是32px(16px * 2)
如何获取google浏览器的默认font-size
var div=document.getElementsByTagName('html')[0] const res = window.getComputedStyle(div).fontSize // 16px console.log(res, 1111)
2.3 rem适配
假设我们的UI图给的尺寸是375px的逻辑像素
.two { font-size:2rem; height: 5rem; width: 5rem; background-color: red; } .three{ font-size:3rem; height: 10rem; width: 10rem; background-color: yellow; }
获取原始值,html的默认font-size为16,意思就是在iphone6下面 375px的UI设计图之下,量出来的应该为: 2rem = 32px 5rem = 80px 3rem = 48px 10rem = 160px 750px的UI设计图,量出来的应该为: 2rem = 64px 5rem = 160px 3rem = 96px 10rem = 320px
适配代码分析
innerWidth 浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏) innerHeight 浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏)
//原理: // 获取屏幕的宽度,然后将屏幕分为多少份(设计稿宽度那么多份) const boxInnerWidth = window.innerWidth // 假设设计稿为375px const UIwidth = 375 // 每份分成多少px const everyPiece = boxInnerWidth/UIwidth // 将html的font-size设置为比例值 document.documentElement.style.fontSize = `${everyPiece * 100}px`
改成以下也可以:
(function () { function changeRootFont() { var UIwidth = 750, rem2px = 100; document.documentElement.style.fontsize = ((window.innerWidth / UIwidth) * rem2px) + 'px'; } changeRootFont(); window.addEventListener('resize', changeRootFont,false); })();
按道理来说,document.documentElement.style.fontSize = ${everyPiece}px 就行了呀,为什么要*100,假设我们在iphone6手机里,那么const everyPiece = boxInnerWidth/UIwidth的everyPiece会等于1px,html的font-size设置为1是不会生效的,所以我们需要将font-size扩大到12倍以上,但是你想这里我扩大了,等我写rem倍数的时候,是不是要除以这个对应的扩大倍数,所以为了好除,我们直接写100,也就是我们量出来的ui里面的px数往右边移动两个小数点就好了
.two { font-size:0.32rem; height: 0.8rem; width: 0.8rem; background-color: red; } .three{ font-size:0.48rem; height: 1.6rem; width: 1.6rem; background-color: yellow; }
3.vw,vh适配
100vw = 一个视口的宽度 1vw = 1%视口的宽度 100vh = 一个视口的高度 1vh= 1%视口的高度
<div class="test"> 哈哈哈哈 </div>
.test { width: calc(100vw * (300 / 375)); height: 100px; background-color: red; color: white; font-size: calc(100vw * (24 / 375)) ; }
假设你在项目中,可以使用sass
@function px2vw($px) { @return $px * 100vw / 375; // 375的设计图 } .test { width: px2vw(300); height: px2vw(100); background-color: red; color: white; font-size: px2vw(24); }
原理: 因为vw是将屏幕分成100份,1vw表示其中的一份,100vw表示的是横向满屏,那么假设我的设计图是375px,目前量的宽是24px,那么 24/375表示是我占屏幕总宽度的24/375,这时候你又知道 屏幕总宽度为100vw,那么动态的宽度为24/375*100vw,而24的尺寸不一,所以封装一个方法来调用
vw,rem的优缺点:
rem:
1.因为是根据html根元素来做其他元素的rem处理的,所以script的代码应该在定义其他元素css之前,必须写在header里面,在触发resize的时候还要再获取window.innerWidth 2.如果是设置的${everyPiece * 100}px这里的比例值不是100,px转成rem会很难算
vw:
1.vw单位兼容性比rem稍差,ios8、安卓4.4及以上才完全支持 2.假设上面这样使用一个方法,写法上看起来我觉得有点怪怪的,没有rem那么直接
所以有了结合版本:(大佬说他就是用的这个,没有任何问题)
html{ font-size:calc(100vw/375*100) } .test { width: 3rem ; height: 1rem; background-color: red; color: white; font-size: 0.24rem }
4.插件推荐(VUE.JS)
参考:
fexible的使用vue项目中使用lib-flexible解决移动端适配的问题
vw (postcss-px-to-viewport,目前在用)
参考(大家可以找个简单的文章看看哈,其实就是个插件):
如何在Vue项目中使用vw实现移动端适配
5.为什么设计师出750px的设计图
参考:
为什么设计稿是750px?
看了很多的文章,大概的意思就是设计图是按照物理像素给的图,这块我也没有说彻底弄懂
6.如果有手机端和pc端如何进行适配
const isMobile = function () { const userAgentInfo = navigator.userAgent let mobileAgents = [ 'Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod', ] return mobileAgents.some(i => userAgentInfo.includes(i)) }
设置全局的isMobileFunc是否为手机端的判断,路由指向同一个页面,这个页面引入pc端的代码,以及mobile的代码,根据isMobile判断显示哪个子组件
适配, var UIwidth = isMobile ? 750 : pcUIWidth, rem2px = 100;
(function () { function changeRootFont() { var UIwidth = isMobile ? 750 : pcUIWidth, rem2px = 100; document.documentElement.style.fontsize = ((window.innerWidth / UIwidth) * rem2px) + 'px'; } changeRootFont(); window.addEventListener('resize', changeRootFont,false); })();
转载地址:https://blog.51cto.com/kuangke/5847155