我们还是老惯例从三个方面,为什么,是什么,怎么做来剖析一个问题
【为什么】
首先讲几个知识点,根本原因需要一些基础知识才能了解透彻
物理像素:
一个设备生产出来,他们的像素就已经确定了,比如iphone5的分辨率是640*1136px,那么水平方向上有640个像素点,竖直方向上有1136个像素点。用放大镜可以肉眼看到多少个四方块,这些四方块就是物理像素。四方块的大小是不会变化的。
image.png
逻辑像素:
也叫设备独立像素或css像素,他的单位也是px,CSS像素是Web编程的概念
设备像素比(Device Pixel Ratio):
DPR = 物理像素 / 逻辑像素
很多年前我们的技术没那么发达,电脑和手机都是单像素的,也就是一个物理像素点(四方块)可以放一个css像素,但是随着技术的发展一个物理像素点(四方块)可以放置四个css像素,甚至更多越多越清晰人眼看的时候。一般的win电脑DPR=1,Mac的DPR=2,iPhone的DPR=2,安卓手机DPR那就很魔鬼了从1到3都见过甚至还MD有小数点。
1.在JavaScript中,通过window.devicePixelRatio来获取
2.在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同DPR的设备,做一些样式适配
image.png
这是同一个网址alert(window.devicePixelRatio)的结果
image.png
所以说了这么多的基础知识点就是为了告诉你为什么原来同样的16px(css像素)的在DPR为1的设备上看的还行但是换成DPR=2或者等于N的设备的话就会变小,因为同样16px占DPR=1的设备16个方块(物理像素),占DPR=2的8个方块(物理像素),占DPR=4四个方块(物理像素)....
所以REM出来就是解决这个问题的!
【是什么】
rem它是CSS3中新增加的一个尺寸(度量)单位,全称font size of the root element,所以他出来时候就是一个字体的单位,而且是相对于根元素(html)的单位,对于元素的宽高不建议用,但是也可以用。
这个单位可谓集相对大小em和绝对大小px的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。
知识点:浏览器的默认字体是16px,所以给html设置font-size=62.5%也就是改变下默认根元素的字体为10px, 然后1rem就等于10px,其实就是为了计算方便。
rem的原理:
(1)本质其实就是等比缩放
(2)clientWidth/UI图宽度 这个是缩放比
【怎么做】
下面是简单的做法,发现不能真正实现不同尺寸手机或者浏览器的等比例,所以弃用
html{
font-size: 62.5%;
}
正确的应该使用JS去监听尺寸再去等比例转化,rem.js有好多种版本可以望网上自行搜索,我测试了一下两种,更倾向于第二种。
正确的步骤为:
(1)//引入 meta
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
(1)添加js
//第一种可行(但是会延迟才执行)
// window.onload = function(){
// //750代表设计师给的设计稿的宽度,你的设计稿是多少
// //下面的10就是一个比例,10px=1rem
// getRem(750,10)
// };
// window.onresize = function(){
// getRem(750,10)
// };
// function getRem(pwidth,prem){
// var html = document.getElementsByTagName("html")[0];
// var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
// html.style.fontSize = oWidth/pwidth*prem + "px";
// }
// //第二种(不会延迟)
!function(n){
var e=n.document,
t=e.documentElement,
//750是设计师给的一般设计稿的宽度iphone7 和ihpneX
//下面的20就是一个比例,20px=1rem, 这样你设计稿是多少100px那就是10rem,因为设计稿根手机存在一个二倍的关系,手机一般DPR是2 。
i=750,
d=i/20,
o="orientationchange"in n?"orientationchange":"resize",
a=function(){
var n=t.clientWidth||320;n>750&&(n=750);
t.style.fontSize=n/d+"px"
};
e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
}(window);
image.png
全部测试代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>rem</title>
<style>
*{
margin: 0;
padding: 0;
}
/* html{
font-size: 62.5%;
}*/
body{
height: 100vh;
background-color: #ccc;
}
.header{
height: 4rem;
width: 100%;
text-align: center;
line-height: 4rem;
background-color: red;
font-size: 3rem;
}
.iconWarp img{
width: 100%
}
.main{
display: flex;
justify-content: space-around;
padding-top: 1rem;
padding-bottom: 1rem;
}
.iconWarp{
width: 12%;
text-align: center;
}
.iconWarp p{
font-size: 2rem;
}
.banner{
width:100%
}
</style>
</head>
<body>
<div class="header">首页</div>
<img class="banner" src="http://pic.zjk169.net/Uploads/Picture/2021-02-09/6021f09f71d83.jpg">
<div class="main">
<div class="iconWarp">
<img src="http://mm.zjk169.net/static/img/icon1.png">
<p>新房</p>
</div>
<div class="iconWarp">
<img src="http://mm.zjk169.net/static/img/icon2.png">
<p>新房</p>
</div>
<div class="iconWarp">
<img src="http://mm.zjk169.net/static/img/icon3.png">
<p>新房</p>
</div>
<div class="iconWarp">
<img src="http://mm.zjk169.net/static/img/icon4.png">
<p>新房</p>
</div>
<div class="iconWarp">
<img src="http://mm.zjk169.net/static/img/icon5.png">
<p>新房</p>
</div>
</div>
<div>
</div>
</body>
<script type="text/javascript">
//第一种可行(但是会延迟才执行)
// window.onload = function(){
// //750代表设计师给的设计稿的宽度,你的设计稿是多少
// //下面的10就是一个比例,10px=1rem
// getRem(750,10)
// };
// window.onresize = function(){
// getRem(750,10)
// };
// function getRem(pwidth,prem){
// var html = document.getElementsByTagName("html")[0];
// var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
// html.style.fontSize = oWidth/pwidth*prem + "px";
// }
// //第二种(不会延迟)
!function(n){
var e=n.document,
t=e.documentElement,
//750代表设计师给的设计稿的宽度,你的设计稿是多少
//下面的20就是一个比例,20px=1rem
i=750,
d=i/20,
o="orientationchange"in n?"orientationchange":"resize",
a=function(){
var n=t.clientWidth||320;n>750&&(n=750);
t.style.fontSize=n/d+"px"
};
e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
}(window);
</script>
</html>
网友评论