移动端布局方案 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即可完成转化工作
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容