移动端布局方案 rem vw

移动端布局方案 rem 示例
[ 方法1 ]
  1. 在谷歌浏览器中,打开任意模仿IPHONE的设备尺寸,查看body的宽度
  2. 将如下JS代码中pageW设置为上一步骤body的layout渲染宽度布
  3. 将PSD等比缩放/拉伸到改尺寸
  4. 安装PSD中尺寸正常测量布局px宽度, 并且在后续,将测量PX转化为REM,比例为 100px = 1rem
  5. 注意添加meta标签,对缩放禁止
(function (doc, win) {
        var pageW = 980;
    var docEl = doc.documentElement,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
        recalc = function () {
            var clientWidth = docEl.clientWidth;
            if (!clientWidth) return;
            if(clientWidth>=pageW){
                docEl.style.fontSize = '100px';
            }else{
                docEl.style.fontSize = 100 * (clientWidth / pageW) + 'px';
            }
        };
    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

模板:

<!DOCTYPE html>
<html lang="en">
<head> 
 <meta charset="UTF-8">  
 <meta name="viewport" content="user-scalable=no">  
<script>   
(function (doc, win) {
            var pageW = 980; 
            var docEl = doc.documentElement,
            resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
            recalc = function () {
                var clientWidth = docEl.clientWidth;
                if (!clientWidth) return;
                if(clientWidth>=pageW){
                    docEl.style.fontSize = '100px';
                }else{
                    docEl.style.fontSize = 100 * (clientWidth / pageW) + 'px';
                }
            };

        if (!doc.addEventListener) return;
        win.addEventListener(resizeEvt, recalc, false);
        doc.addEventListener('DOMContentLoaded', recalc, false);
    })(document, window);
</script> 
 /*你引进的资源*/
<title>标题</title> 
</head>
<body>
 /*你的代码*/
</body>
</html>
[ 方法2 ] - 网络参照 [ 小米官网 ]
  1. i的参数设置为PSD设计稿实际尺寸,如下面例子中,PSD设计稿假设为720
  2. 正常测量PX,然后按照100px = 1rem的比例计算
  3. 因为设置了meta的 width=device-width 所以不用考虑其他因素了
    代码:
!function(n){
    var  e=n.document,
         t=e.documentElement,
         i=720,
         d=i/100,
         o="orientationchange"in n?"orientationchange":"resize",
         a=function(){
             var n=t.clientWidth||320;
             if(n>720){ n=720 };
             t.style.fontSize=n/d+"px"
         };
         e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
}(window);
模板[ REM ]
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <script>
    //小米官网的写法
    !function(n){
    var  e=n.document,
         t=e.documentElement,
         i=720,
         d=i/100,
         o="orientationchange"in n?"orientationchange":"resize",
         a=function(){
             var n=t.clientWidth||320;
             if(n>720){ n=720 };
             t.style.fontSize=n/d+"px"
         };
         e.addEventListener&&(n.addEventListener(o,a,!1),e.addEventListener("DOMContentLoaded",a,!1))
  }(window);
    </script>
    <style>
    body { margin:0;}
        .wrap{position:absolute;top:0;left:0;bottom:0;right:0;background:#fefefe;}
        .title{width:100%;height:0.98rem;line-height:0.98rem;color:#fff;background:#e02222;text-align: center;font-size:0.32rem;}
    </style>
</head>
<body>
    <div class="wrap">
        <div class="title">首页</div>
    </div>
</body>
</html>
[ 方法三]
  1. js会动态添加meta,以及html的font-size,并且改变他们在不同设备下的数值
  2. 需要借助谷歌浏览器模拟任意iphone尺寸设备,测量body的宽度,
  3. 将PSD设计稿等比调整至改值
    例:如下
    在IPHONEX设备模拟下,body宽度为1125,将其分为45份,每份为25,则该尺寸下html的font-size为25
    当然为了方便计算,可以将此数值改为 11.25份,每份为100,则该尺寸下html的font-size为100
;(function(){
    function setViewport(){
        //获取像素比 - window.devicePixelRatio
        var dpr = 1 / window.devicePixelRatio;
        if(!document.getElementById('viewPortMeta')){
            var oMeta = document.createElement('meta');
            oMeta.name = "viewport";
            oMeta.id = "viewPortMeta";
            oMeta.content = "width=device-width,user-scalable=no,initial-scale="+dpr+",minimum-scale="+dpr+",maximum-scale="+dpr;
            document.getElementsByTagName('head')[0].appendChild(oMeta);        
        }
        var fz = document.documentElement.clientWidth / 45; 
        /*25*/
        document.getElementsByTagName('html')[0].style.fontSize = fz + 'px';
    }
    setViewport();
    
    //resize
    if(window.orientation){
        window.addEventListener('orientationchange',function(){
            setViewport();  
        },false);
    }else{
        window.addEventListener('resize',function(){
            setViewport();  
        },false);
    }   
})();
模板中
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>标题</title>
</head>

<body>
    正文
</body>
</html>
<script type="text/javascript" src="js/viewport.js"></script>

区别优劣?

上面2个方法,

  1. 方法一,借助浏览器模拟IPHONE任意设备宽度,测量BODY渲染宽度,将PSD设计稿等比拉为此宽度,并且将JS中pageW修改为该值; 换算 [ 100px = 1rem ]
    【注】: 微信浏览器 部分标签因为结构嵌套过于靠外,dom load 第一次渲染错误,orientationchange 触发会正常

可以修改结构,靠外元素需要单独嵌套1层,另外,最外面盒子需要添加rem为单位的宽度

  1. 方法二,只需要考虑设计稿,根据设计稿宽度设置脚本参数,HTML的 head中添加一段默认meta设置; 换算 [ 100px = 1rem ]

  2. 方法三,借助浏览器模拟IPHONE任意设备宽度,测量BODY渲染宽度,将PSD设计稿等比拉为此宽度,人为设置HTML划分多少份,计算html的font-size值以便后续计算;
    如上例子中,1125宽度,45份,每份为25 ,则换算 需要根据实际情况 [ 25px = 1rem ]
    【注】:部分安卓机器需要测试兼容性

法1会好一些,方便计算
  1. 将chrome切换移动端任意尺寸手机型号,查看computed的body宽度,
  2. 将PSD等比调整至此宽度,
  3. 将JS脚本中的pageW参数设置为改尺寸宽度,
  4. 最后进行切图,以及PX和REM转换
  5. 添加禁止缩放
<meta name="viewport" content="user-scalable=no">
方法1存在的问题

渲染问题,页面加载后有一个变化的过程,目力可见,不友好
解决方法:

  1. 将改变font-size脚本提到head标签内,在读取页面结构中,提前计算字体大小
  2. 将body隐藏,计算完font-size后,再显示body,使用visibility来做这个隐藏操作
  3. 行内块级元素,上下有空白高度,设置这个容器 font-size为0即可
  4. 在chrome模拟器上看没问题,真机出现字体首次渲染不到位,但是通过渲染手机横屏触发了二次渲染正常的话,需要在这个首次渲染问题的标签父级,增加font-size:0 即可
  5. 通过rem方式来布局,body上面必须要设置一个font-size, 例如: font-size:14px;或font-size:16px; 当然也可以使用rem
B站 的移动端布局方案

传统html设置字体,通过rem调整页面layout尺寸

var docEl = document.documentElement;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var visibleRatio = 0.72;

//设置html标签字体
var recalc = function () {
  var clientWidth = docEl.clientWidth;
  var clientHeight = docEl.clientHeight;
  if (!clientWidth) {
      return;
  };
  if (clientWidth >= 750) {
    if (clientWidth / clientHeight < visibleRatio) {
      docEl.style.fontSize = '100px';
    } else {
      //宽度大于750且宽高比大于0.72,那么让宽度等于高度的0.72
      var w = visibleRatio * clientHeight;
      docEl.style.fontSize = 100 * (w / 750) + 'px';
    }
  }else {
    //常规移动端,html字号 750宽 = 100px ,适配设备的宽*100/750 = 当前字号
    docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
  }
};
window.addEventListener(resizeEvt, recalc, false);
document.addEventListener('DOMContentLoaded', recalc, false);
[ 最简洁方案VW布局]

VW结合REM布局

  1. 节省了常规通过计算视窗变化,重新计算HTML上font-size设置值的过程,一劳永逸
    直接设置 html { font-size:26.6667vw; }
    26.6667的由来,iPhone6\7\8 宽度为375px 一屏幕宽为100vw,如果求1px等于多少vw
    便可以计算得知 1px100vw/375px = 0.266667vw ;
    那么如果设置字体大小为100px = 100
    0.266667vw = 26.6667vw
    而在iPhone6plus/7plus/8plus/时候,宽度为414px 乘以0.26667vw 可得110px,这与iphone6/7/8的100px 是等比变化的
    如:
    375/414 = 100/110 ; 这样就做到了vw一劳永逸的目的
  2. 将PSD调整为375进行PX布局,通过VsCode插件 px2rem配置基础font-size为100
    圈选px样式部分,通过快捷键crtil+Z一次性调整为rem单位
  3. 注意为body设置基础px值,防止页面渲染问题
    body上的font-size主要是针对字体的,html上的font-size主要是针对布局的

最终代码:

html { font-size:26.666667vw;}
body {font-size:16px;} 

/*布局代码区域*/
设计图以iphone6/7/8 375尺寸为准,直接量取px即可,
后续通过VScode工具(px to rem)设置好参数 Number of pixels per 1rem项目为100
然后圈选CSS样式alt+z即可完成转化工作
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容