rem适配方案
1. 介绍
1.1. 动态 Rem 方案既能实现页面级整体缩放,又能个性化控制某些元素不缩放
1.2. 基于这个原理,对于需要适配屏幕等比缩放的元素可以选用 rem 作为单位,对于不需要等比缩放的元素依旧使用 px 作为单位
1.3只要调整html标签的 font-size,就能让所有使用 rem 单位的元素跟随着发生变化,而使用 px 单位的元素不受影响
2. 实施
设计稿宽度是750px,设计稿上一个div的标注尺寸是375px(宽度是设计稿宽度的一半),我们可以
- 设置 html 的 font-size 为 100*屏幕宽度/设计稿宽度
- 在写 CSS 时设置 div 的宽度是 3.75rem(计算时用设计稿标注值除以100),边框宽度为 1px
3. 疑问
3.1 难点之处
若屏幕宽度375 设计图纸750 375/750=0.5 0.5*100=50px 则html的fontSize为50px
那么此刻1rem == 50px 3.75rem = 187.5px(是屏幕宽度的一半) 7.5rem = 375px(是整个屏幕的大小)
(1)在750px设计图中p标签的宽度为450px 450/750
(2)那么按照这个比例,在375px的屏幕上应该显示为多少? x/375
按照数学公式来算的话:
450/750 = x/375 推出x=200px
(3)那么200px应该在设置多少rem呢?
因为1rem = 50px 那么 200/50 = 4rem 因此需要4rem才能符合在设计中的400px要求
此时是不是很意外,设计图要求400px,我们写4rem 150px,我们写1.5rem,为什么呢?
因为比例取得好,我们取了100px作为基数来乘以 (屏幕宽度/设计稿宽度)
1.如果取100, 375/750*100=50px 即1rem=50px
此时设计图有一个div,分别的尺寸为300 420
当div尺寸为300px,基数取100时:
设计图尺寸 手机上尺寸应
300 x
———— = ———— x=>150 手机上尺寸应该为150px 转化为rem 150/50=3rem
750 375
设计图尺寸 手机上尺寸应
420 x
———— = ———— x=>210 手机上尺寸应该为210px 转化为rem 210/50=4.2rem
750 375
你会发现最后换算的结果总是与设计图中div的尺寸相差了100倍 那么就是我们那时取的100基数
那么写的时候设计图300px 那么只要取小100倍即可
2.如果取50, 375/750*50=25px 即1rem=25px
此时设计图有一个div,分别的尺寸为300 420
当div尺寸为300px,基数取100时:
设计图尺寸 手机上尺寸应
300 x
———— = ———— x=>150 手机上尺寸应该为150px 转化为rem 150/25=6rem
750 375
设计图尺寸 手机上尺寸应
420 x
———— = ———— x=>210 手机上尺寸应该为210px 转化为rem 210/50=8.4rem
750 375
你会发现最后换算的结果总是与设计图中div的尺寸相差了50倍 那么就是我们那时取的50基数
那么写的时候设计图300px 那么需要除以100乘以2
3.那好像可以直接不用设置基数 方案2
375/750 = 0.5 1rem=0.5px
如果div是750的,在手机上不就是750rem吗? 750rem = 750*0.5=375px 刚好是手机的屏幕大小
那不就是设计图多少,实际你写多少就行,实际上把尺寸缩小一倍
发现写750rem好像太大了,想写小一点,那么就有了上面的基数产生,将font-size=0.5放大100倍
那么就是50px,最后写7.5rem就行
当 1rem = 0.5px 时,
设计图div尺寸 手机
375px 375rem=375*0.5=187.5px div占设计图一半 摆在手机也是占一半
当 1rem = 50px 时,
设计图div尺寸 手机
375px 3.75rem=3.75*50=187.5px 同上
3.2 为什么要用 100 来乘以屏幕宽度/设计稿宽度?
其实 100 只是随便选取的一个值,我们也可以随便其他任意值比如 50。如果选 100,
设计稿中某个元素标注的尺寸是 375px,我们可以很快速的计算出 3.75rem。如果 html 的 font-size
设置为 50*屏幕宽度/设计稿宽度,那么 div 的宽度就应该是 7.5rem了。换算起来就没那么直观了。
4. 版本1:没设置任何的边界值
// 封装rem适配H5项目
; (function rem() {
let dw = 750 // 设计图宽度
let sw = window.screen.width // 屏幕宽度
let fontSize = (sw / dw * 100) // 方案1
// let fontSize = (sw / dw) // 方案2
let oHtml = document.getElementsByTagName('html')[0]
oHtml.style.fontSize = fontSize + 'px'
window.onresize = function (event) {
rem();
}
})();
版本2:设置边界值
// 封装rem适配H5项目
; (function rem() {
let dw = 750 // 设计图宽度
let sw = window.screen.width // 屏幕宽度
let fontSize = (sw / dw * 100) // 方案1
// let fontSize = (sw / dw) // 方案2
let oHtml = document.getElementsByTagName('html')[0]
oHtml.style.fontSize = fontSize + 'px'
// 设置边界
const boundary = ()=>{
if(sw>580){
oHtml.style.fontSize = 64 + 'px'
}
if(sw<300){
oHtml.style.fontSize = 40 + 'px'
}
}
boundary()
window.onresize = function (event) {
rem();
boundary();
}
})();
5.例子
<!-- <div id="app">
<div class="nomal_wrap">正常尺寸</div>
<div class="rem_aa"></div>
</div> -->
<div id="test">
<nav>
<div class="title">
<img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524173501.png" alt="">
</div>
<div class="upload">下载APP</div>
</nav>
<div class="list-item">
<img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524174945.png" alt="">
<img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524174958.png" alt="">
<img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524175109.png" alt="">
</div>
<div style="border-bottom:10px solid rgb(235, 229, 229);"></div>
<div class="new-list">
<div class="item">
<div class="txt">
<div>日民众游行抗议:阻止日美"侵略中国" 别把日本变战场</div>
<div class="editor">环球时报</div>
</div>
<div class="img"><img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524195507.png" alt=""></div>
</div>
</div>
<div class="new-list">
<div class="item">
<div class="txt">
<div>日民众游行抗议:阻止日美"侵略中国" 别把日本变战场</div>
<div class="editor">环球时报</div>
</div>
<div class="img"><img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524195507.png" alt=""></div>
</div>
</div>
<div class="new-list">
<div class="item">
<div class="txt">
<div>日民众游行抗议:阻止日美"侵略中国" 别把日本变战场</div>
<div class="editor">环球时报</div>
</div>
<div class="img"><img src="http://rcabqe9ry.hn-bkt.clouddn.com/20220524195507.png" alt=""></div>
</div>
</div>
</div>
<div class="aaa"></div>
* {
margin: 0;
padding: 0;
}
.nomal_wrap {
width: 250px;
height: 100px;
background-color: pink;
font-size: 16px;
}
.rem_aa {
background-color: cadetblue;
color: aliceblue;
line-height: 50px;
/* 需要随屏幕等比缩放,使用rem单位,比如设计稿中标注的32px这里写成0.32rem */
width: 3rem;
/*不需要缩放的部分用px*/
height: 50px;
border: 1px solid #ccc;
margin-bottom: 20px;
}
/* 新闻音乐案例 */
/*
把宽 高 padding margin font-size 都用rem进行等比例缩放 border可以不需要
使用vscode插件:px to rem & rpx & vw (cssrem) alt+z 快捷键可以一键转换为rem
*/
/* 导航 */
nav {
display: flex;
justify-content: space-between;
padding: 0 .3rem;
box-sizing: border-box;
height: 1.12rem;
background-color: #d43c33;
align-items: center;
}
nav .title img {
display: block;
width: 3.2rem;
}
nav .upload {
font-size: .28rem;
color: #fff;
}
/* 图片 */
.list-item {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.list-item img {
width: 33.33%;
}
/* 新闻 */
.new-list {
font-size: .32rem;
box-sizing: border-box;
margin: 0 .2rem;
padding: .2rem 0;
/* background-color: pink; */
/* border这种不需要rem等比例缩放 写成px即可 */
border-bottom: 1px solid #e4e4e4;
}
.new-list .item {
display: flex;
justify-content: space-around;
}
.new-list .item .img {
margin-left: .24rem;
}
.new-list .item .img img {
width: 1.92rem;
height: 1.28rem;
}
.new-list .item .editor {
/* background-color:chocolate; */
border: .02rem solid #d43c33;
margin-top: 0.2rem;
font-size: .28rem;
width: 3rem;
height: 0.6rem;
}
.aaa {
height: 20px;
background-color: #d43c33;
}
// 封装rem适配H5项目
; (function rem() {
let dw = 750 // 设计图宽度
let sw = window.screen.width // 屏幕宽度
let fontSize = (sw / dw * 100) // 方案1
// let fontSize = (sw / dw) // 方案2
let oHtml = document.getElementsByTagName('html')[0]
oHtml.style.fontSize = fontSize + 'px'
// 设置边界
const boundary = () => {
if (sw > 580) {
oHtml.style.fontSize = 64 + 'px'
}
if (sw < 300) {
oHtml.style.fontSize = 40 + 'px'
}
}
boundary()
window.onresize = function (event) {
rem();
boundary();
}
})();
效果图: