移动端适配rem/vw,vh原理(详细)

您所在的位置:网站首页 移动端适配方案的具体实现原理包括什么 移动端适配rem/vw,vh原理(详细)

移动端适配rem/vw,vh原理(详细)

2024-01-01 13:48| 来源: 网络整理| 查看: 265

了解像素相关知识: 移动端适配 掌握web开发基础系列--物理像素、逻辑像素、css像素 为什么给750px的设计图

其实我一直很想写一些关于适配方面的文章,因为很多东西只有实践才能对这个知识点更加的了解,而不是查几篇文章就行了~

我希望能够解答这些问题:

1.什么是物理像素,和逻辑像素,DPR2.为什么我们的设计师给的尺寸都是750px3.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

image.png

Document 我是根元素html的大小 我是两倍 我是三倍 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; }

image.png

比如上面这个例子,虽然我只设置了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)

image.png

1625394225(1).png

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适配

image.png

100vw = 一个视口的宽度 1vw = 1%视口的宽度 100vh = 一个视口的高度 1vh= 1%视口的高度 哈哈哈哈 .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) rem (fexible.js,2年前的项目用过)

参考: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); })();

BTY,关于rem,vw适配更多的优缺点,欢迎评论,后续会将fexible.js和postcss-px-to-viewport的插件使用贴出来

-_-奥利给



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3