手机布局rem的使用(rem)
最后一堆代码是举例的全码.
一 直接<head>标签里套用以下,其他都不用
1 <script> 2 document.documentElement.style.fontSize = document.documentElement.clientWidth / 750*100 + "px"; 3 window.addEventListener("resize",function(){ 4 document.documentElement.style.fontSize = document.documentElement.clientWidth / 750*100 + "px"; 5 },false); 6 </script>
早就听说布局总共约4种:
静态布局 , 流式布局 , 响应式布局 , 自适应布局(以下是解释和区别 , 不敢保证正确 , 但个人认同)
静态布局:
根据固定宽度, 完成布局,在屏幕的分辨率不同 , 显示也不同;
流式布局:
当浏览器宽度小于多少时怎么显示布局 ;当浏览器宽度大于多少时, 怎么显示布局 ; 展示的方向像水流一样,一部分一部分的加载 ,额不知道花瓣网是不是就算;
响应式和自适应的共同点:
都是自动检测设备, 根据设备的不同 ,自动采用不同的css ,而且css都是采用的百分比等单位 ,而不是固定的宽度单位;
响应式和自适应的不同点:
在不同设备上看上去不同;
响应式会随设备的改变而响应改变布局的样式;
自适应是在所有设备上看都是固定的样式 ,好像采用一个模板一样;
二 参考
本篇有大部分摘抄大神的http://www.cnblogs.com/mufc-go/p/4625115.html ,谢谢无偿分享 .
代码有更新,最好直接查看github
github:https://github.com/finance-sh/adaptive
adaptivejs利用rem解决移动端页面开发的自适应问题
页面模板初始化的时候不用设置viewport标签,由js生成。
我们在head标签的顶部引入js,按以下方法使用即可
adaptivejs原理:
利用rem布局,根据公式
html元素字体大小 = document根节点(html)宽度 * 100 / 设计图宽度
计算html元素的font-size,使1rem等于100px,方便快速开发
开发时,一个div设计图宽度为89px,那么在css中我们可以这样书写:width:0.89rem;
如果是文字,我们也建议使用rem
对于iphone的retina高清显示屏,基本版本(adaptive.js)我们做了缩放处理,以达到最佳显示效果。 对于快速开发版本(adaptive-version2.js),viewport的width等于设备宽度,不会缩放
以下是
adaptivejs
var adaptive = {}; (function (win, lib) { var doc = win.document; var docEl = doc.documentElement; // 设备像素比 var devicePixelRatio = win.devicePixelRatio; // 我们设置的布局视口与理想视口的像素比 var dpr = 1; // viewport缩放值 var scale = 1; // 设置viewport function setViewport() { // 判断IOS var isIPhone = /iphone/gi.test(win.navigator.appVersion); if (lib.scaleType === 2 && isIPhone || lib.scaleType === 3) { dpr = devicePixelRatio; } // window对象上增加一个属性,提供对外的布局视口与理想视口的值 win.devicePixelRatioValue = dpr; // viewport缩放值,布局视口缩放后刚好显示成理想视口的宽度,页面就不会过长或过短了 scale = 1 / dpr; // 获取已有的viewport var hasMetaEl = doc.querySelector('meta[name="viewport"]'); var metaStr = 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'; if (dpr === 1) { metaStr = 'width=device-width, '.concat(metaStr); } if (!isIPhone && dpr !== 1) { metaStr = metaStr.concat(', target-densitydpi=device-dpi'); } // 如果有,改变之 if (hasMetaEl) { hasMetaEl.setAttribute('content', metaStr); } // 如果没有,添加之 else { var metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', metaStr); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var containDiv = doc.createElement('div'); containDiv.appendChild(metaEl); docEl.appendChild(containDiv); } } } var newBase = 100; lib.errDpr = 1; function setRem() { // 布局视口 // var layoutView = docEl.clientWidth; 也可以 获取布局视口的宽度 var layoutView; if (lib.maxWidth) { layoutView = Math.min(docEl.getBoundingClientRect().width, lib.maxWidth * dpr); } else { layoutView = docEl.getBoundingClientRect().width; } // 为了计算方便,我们规定 1rem === 100px设计图像素,我们切图的时候就能快速转换 // 有人问,为什么不让1rem === 1px设计像素呢? // 设计图一般是640或者750px // 布局视口一般是320到1440 // 计算一个值,使layout的总宽度为 (desinWidth/100) rem // 那么有计算公式:layoutView / newBase = desinWidth / 100 // newBase = 100 * layoutView / desinWidth // newBase = 介于50到200之间 // 如果 1rem === 1px 设计像素,newBase就介于0.5到2之间,由于很多浏览器有最小12px限制,这个时候就不能自适应了 newBase = 100 * layoutView / lib.desinWidth * (lib.errDpr || 1); docEl.style.fontSize = newBase + 'px'; // rem基准值改变后,手动reflow一下,避免旋转手机后页面自适应问题 doc.body&&(doc.body.style.fontSize = lib.baseFont / 100 + 'rem'); // 重新设置rem后的回调方法 lib.setRemCallback&&lib.setRemCallback(); lib.newBase = newBase; } var tid; lib.desinWidth = 750; lib.baseFont = 28; // 局部刷新的时候部分chrome版本字体过大的问题 lib.reflow = function() { docEl.clientWidth; }; // 检查安卓下rem值是否显示正确 function checkRem() { if (/android/ig.test(win.navigator.appVersion)) { var hideDiv = document.createElement('p'); hideDiv.style.height = '1px'; hideDiv.style.width = '2.5rem'; hideDiv.style.visibility = 'hidden'; document.body.appendChild(hideDiv); var now = hideDiv.offsetWidth; var right = lib.newBase * 2.5; if (Math.abs(right / now - 1) > 0.05) { lib.errDpr = right / now; setRem(); } document.body.removeChild(hideDiv); } } lib.init = function () { // resize的时候重新设置rem基准值 // 触发orientationchange 事件时也会触发resize,故不需要再添加此事件了 win.addEventListener('resize', function () { clearTimeout(tid); tid = setTimeout(setRem, 300); }, false); // 浏览器缓存中读取时也需要重新设置rem基准值 win.addEventListener('pageshow', function (e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(setRem, 300); } }, false); // 设置body上的字体大小 if (doc.readyState === 'complete') { doc.body.style.fontSize = lib.baseFont / 100 + 'rem'; checkRem(); } else { doc.addEventListener('DOMContentLoaded', function (e) { doc.body.style.fontSize = lib.baseFont / 100 + 'rem'; checkRem(); }, false); } setViewport(); // 设置rem值 setRem(); // html节点设置布局视口与理想视口的像素比 docEl.setAttribute('data-dpr', dpr); }; // 有些html元素只能以px为单位,所以需要提供一个接口,把rem单位换算成px lib.remToPx = function (remValue) { return remValue * newBase; }; })(window, adaptive); if (typeof module != 'undefined' && module.exports) { module.exports = adaptive; } else if (typeof define == 'function' && define.amd) { define(function() { return adaptive; }); } else { window.adaptive = adaptive; }
注意:如果设计图宽度大于document的宽度,0.01rem将小于1px,故如果设计图是1px,在css中仍然用1px显示。
可用的全局变量:window.devicePixelRatioValue 当前页面设置的设备像素比
优化宽度问题
新增最大宽度,解决平板或手机横屏时体验不佳的问题
window['adaptive'].maxWidth = 480; // 设置最大宽度,默认540px
需要css配合使用,添加如下代码:
body {
max-width: 6.4rem; // 设计图宽度为640px时为6.4rem ,750时为7.5rem ,以此类推
margin: 0 auto;
}
body * {
max-width: 6.4rem; // 设计图宽度为640px时为6.4rem ,750时为7.5rem ,以此类推
}
// 设计图宽度 window['adaptive'].desinWidth = 640; // body 字体大小 会将body字体大小设置为 baseFont / 100 + 'rem' 750的设计图一般设置为28,640的设计图一般设置为24 window['adaptive'].baseFont = 24; /* // 显示最大宽度 可选 window['adaptive'].maxWidth = 480; // rem值改变后执行方法 可选 window['adaptive'].setRemCallback = function () { alert(1) } // scaleType 1:iphone andriod下viewport均无缩放 2:iphone下viewport有缩放,andriod没有 3:iphone andriod下viewport均有缩放; 默认值为1 window['adaptive'].scaleType = 1; */ // 初始化 window['adaptive'].init();
项目html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <meta content="yes" name="apple-mobile-web-app-capable"> 6 <meta content="no" name="apple-touch-fullscreen"> 7 <meta content="telephone=no,email=no" name="format-detection"> 8 <meta name="App-Config" content="fullscreen=yes,useHistoryState=yes,transition=yes"> 9 <meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> 10 <link rel="stylesheet" type="text/css" href="css/common.css"/> 11 <link rel="stylesheet" type="text/css" href="css/yunxian.css"/> 12 <script src="js/jquery-1.10.1.min.js"></script> 13 <script src="js/adaptive.js"></script> 14 <script src="js/yunxian.js"></script> 15 <script> 16 window['adaptive'].desinWidth = 750; 17 window['adaptive'].baseFont = 28; 18 window['adaptive'].maxWidth = 480; 19 window['adaptive'].scaleType = 2; 20 window['adaptive'].init(); 21 </script> 22 <title>车险</title> 23 </head> 24 <body> 25 <form action="" method="post"> 26 <div class="yx1"> 27 <div class="yx1_menu"> 28 选择行驶证类型 29 </div> 30 <div class="yx1_con"> 31 <span> 32 <img id="checkimg1" src="img/chose1.png"/> 个人 33 </span> 34 <span> 35 <img id="checkimg2" src="img/chose2.png"/> 企业 36 </span> 37 </div> 38 </div> 39 <div class="yx_personal"> 40 <div class="yx_pl"> 41 </div> 42 <div class="yx_pr"> 43 <div class="yx_prcon1"> 44 投保人 <input type="text" placeholder=" 公司名称或姓名" /> 45 </div> 46 <div class="yx_prcon1"> 47 身份证号 <input class="idnummer" type="text" placeholder=" 机构请填写组织机构代码证" /> 48 </div> 49 <div class="yx_prcon1" style="border:none ;"> 50 地址 <input type="text" placeholder=" " /> 51 </div> 52 </div> 53 </div> 54 <div class="yx_car"> 55 <div class="yx_cl"> 56 </div> 57 <div class="yx_cr"> 58 <div class="yx_crcon1"> 59 <span class="menu_safe">是否首次投保 </span> 60 <div class="yx_crcon11"> 61 <span> 62 <img id="yx_crcon_yes" src="img/chose1.png"/> 是 63 </span> 64 <span> 65 <img id="yx_crcon_no" src="img/chose2.png"/> 否 66 </span> 67 </div> 68 </div> 69 <div class="yx_crcon1"> 70 车牌号码 <input type="text"/> 71 </div> 72 <div class="yx_crcon1"> 73 所有人/车主 <input type="text" class="yx_input3"/> 74 </div> 75 <div class="yx_crcon1"> 76 品牌型号 <input type="text"/> 77 </div> 78 <div class="yx_crcon1"> 79 发动机型号 <input type="text"/> 80 </div> 81 <div class="yx_crcon1"> 82 车辆识别代码/VIN码/车架号 <input type="text" class="yx_input6"/> 83 </div> 84 <div class="yx_crcon1"> 85 注册日期/初等日期 <input type="text" class="yx_input7"/> 86 </div> 87 <div class="yx_crcon1"> 88 核定载人数 <input type="text" placeholder=" 输入货物数量 如:20吨 " /> 89 </div> 90 <div class="yx_crcon1" style="border:none ;"> 91 核定载质量/整备质量 <input type="text" class="yx_input9"/> 92 </div> 93 </div> 94 </div> 95 <div class="yx_safemenu"> 96 <div class="yx_safemenul"> 97 </div> 98 <div class="yx_safemenur"> 99 <div class="yx_safemenucon"> 100 投保险种 <a href=""> 101 <input type="text" class="more" value=" XXXXXDDDDDDDD"/> 102 </a> 103 </div> 104 </div> 105 </div> 106 <div class="information"> 107 <div class="load"> 108 <img src="img/idcard1.png"/> 109 <div></div> 110 </div> 111 <div class="load"> 112 <img src="img/idcard2.png"/> 113 <div></div> 114 </div> 115 <div class="load"> 116 <img src="img/companycard.png"/> 117 <div></div> 118 </div> 119 <div class="load"> 120 <img src="img/carcard.png"/> 121 <div></div> 122 </div> 123 </div> 124 <div class="deal"> 125 <input type="checkbox" /> 126 我已阅读并同意<a href="">《人保保险投保须知》</a> 127 </div> 128 <div class="submit"> 129 <input type="submit" value="提交资料"/> 130 </div> 131 </form> 132 </body> 133 </html>