缩放方案
viewport缩放
原理: 按照设计稿还原不关注屏幕尺寸的大小,页面完成后在head标签内加入 <meta name="viewport" content="width={设计稿宽度},initial-scale={屏幕逻辑像素宽度/设计稿宽度}>"
,通过对页面的缩放来达到对内容对屏幕的填充。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
const WIDTH = 750
const mobileAdapter = ()=> {
let scale = screen.width/WIDTH //screen.width获取屏幕的宽度
let content = `width=${WIDTH},initial-scale=${scale},maximum-scale=${scale},minmum-scale=${scale}`
let meta = document.querySelector('meta[name=viewport]')
if(!meta){
meta = document.createElement('meta')
meta.setAttribute('name','viewport')
document.head.appendChild(meta)
}
meta.setAttribute('content',content)
}
mobileAdapter()
window.onorientationchange = mobileAdapter //设备切换屏幕纵横时在重新获取屏幕宽度
//orientationchange事件在设备的纵横方向改变时触发
//orientationchange目前弃用,需自写js监测window.orient
</script>
</head>
<body>
</body>
</html>
优点:开发流程简单,只需按设计稿来还原页面,无需额外计算。适配范围广。
缺点:页面整体放大缩小,对于不想缩放的元素无法控制。比如边框在大屏手机下显得很粗,在小屏手机下很细
动态REM
原理:使用相对单位rem来控制页面大小,由于1rem等于html标签font-size的一倍。基于这个可以适配屏幕等比缩放的元素可以选用rem为单位,对于不需要等比缩放的元素依旧使用px作为单位。
设计方法:
- 设置html的font-size为100*屏幕宽度/设计稿宽度
- 在写CSS时设置div的宽度为3.75rem(计算时用设计稿标注除以100),边框宽度为1px
- 100为随便取的值,方便计算
假如用户在375px的设备上打开,则html的font-size是100*375/750=50px,若div宽度为3.75rem,则为187.5px
html
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Rem-Layout</title>
<link href="style.css" rel="stylesheet">
<script>
const WIDTH = 750 //设计稿尺寸
const setView = ()=>{ //设置html标签的fontSize
document.documentElement.style.fontSize = (100*screen.width/WIDTH) + 'px'
}
window.onorientationchange = setView
setView()
</script>
<style>
div{
width:3.75rem /*设计稿为375px*/
}
</style>
</head>
<body>
</body>
</html>
vw适配
原理:vw是相对单位,1vw表示屏幕宽度的1%,适配部分通过vw作为单位,不需要缩放的元素使用px做单位
举例,设计稿宽度为750px,标题内容fontSize标注尺寸为32px。(32/750)*100%=4.27%,标题尺寸占屏幕宽度的4.27%。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.button {
width: 16vw; /* 100vw*120/750 */
font-size: 3.73vw; /* 100vw*28/750 */
line-height: 6.4vw; /* 100vw*48/750 */
border: 1px solid #000; /*不需要缩放的部分用px*/
text-align: center;
}
</style>
</head>
<body>
<div class="button">按钮</div>
</body>
由于需要换算可以使用calc来换算
css
:root {
--ratio: calc(100vw/750);
}
.button {
font-size: calc(100vw*28/750); /* 直接用calc */
line-height: calc(100vw*48/750);
width: calc(120*var(--ratio)); /* 可以用calc配合var使用,IE不支持 */
border: 1px solid #000; /*不需要缩放的部分用px*/
text-align: center;
}
我们也可以使用SCSS,把换算交给预处理器
css
@function px2vw($px) {
@return $px * 100vw / 750;
}
.button {
width: px2vw(120);
font-size: px2vw(28);
line-height: px2vw(48);
border: 1px solid #000;
text-align: center;
}
适配方案对比
viewport缩放
- 适配原理简单
- 需要使用JS
- 直接使用无需换算
- 方案死板只能实现页面级别整体缩放
动态REM方案
- 适配原理复制
- 需要使用JS
- 通过HTML的fontSize来决定,换算css的rem
- 可整体缩放也可局部缩放
vw方案
- 适配原理简单
- 不需JS即可适配
- 换算vw计算复杂
- 可整体缩放也可局部缩放