Skip to content

缩放方案

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作为单位。

设计方法:

  1. 设置html的font-size为100*屏幕宽度/设计稿宽度
  2. 在写CSS时设置div的宽度为3.75rem(计算时用设计稿标注除以100),边框宽度为1px
  3. 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计算复杂
    • 可整体缩放也可局部缩放