本文大多数的内容基本都是从多篇博客或相关文章中进行筛选,提炼出来,本来我也想用我匮乏的语言来描述,可是发现别人已经总结的更好了,因此...我仍是乖乖的站在巨人的肩膀上吧~~javascript
完整目录:css
基本概念
物理像素
设备独立像素
CSS 像素
PPI的概念
DPR的概念
缩放的概念
viewPort 的概念
viewport 渲染流程
Meta 标签说明html
移动端布局实践
混合方式
REM 方式
响应式
JS自动换算
缩放方式
CSS3 缩放
viewport 缩放前端
相关补充
为何须要meta标签?
传统响应式布局与移动端响应式的区别
移动端字体以及大小的设置
移动端背景图缩放设置
使用Sass提升px与rem转换效率
经过Chrome进行真机调试
weinre 远程调试java
混合方式实现的移动端布局实际上就是对PC端布局技术的组合使用,它主要包含如下技术:android
将这些布局方法根据页面每一个不一样部分的特性进行组合使用,例如模态框,弹出层等能够采用定位方式,而页面元素的排版能够采用浮动布局,也可使用具备可塑性的Flex布局方案,对于元素的尺寸能够采用百分比或者其它相对单位,而这即是我称之为“混合方式”的缘由。
混合方式进行的移动端网页布局,所采用的技术一般都具备灵活、可伸缩、可塑等特色,甚至连使用的单位,最好都是相对单位,也只有这样才能知足屏幕尺寸多样性的移动设备。ios
对于混合布局技术,我首先要说几点我认为比较重要的基础知识点:css3
· 声明meta标签
经过meta标签来声明viewport是进行手机端页面开发的必须也是起始步骤git
<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no />
· 百分比计算公式
若是你在进行移动端网页布局中使用到了百分比单位,那么这个公式你必定要清楚github
百分比 = 目标尺寸 / 上下文尺寸。
其中目标尺寸就是当前元素的尺寸,而上下文尺寸则是包含当前元素的父元素,经过 目标尺寸 / 上下文尺寸
即可以获得咱们须要的百分比结果,另外我的建议百分比结果保留全部小数。
· 设置阀值
可伸缩的布局方案有一个本质特色就是会根绝显示设备的尺寸进行自适应调整,这一特性自己就是咱们所期待的,可是在某些极端的环境下,好比过大或太小的屏幕下,某些元素尺寸也会变的过大或者太小,或者图片被严重拉伸,致使失真等,从而使显示效果变的不好,而下面的这些CSS属性就能够很简单解决这些问题。
max-width: //设置最大宽度阈值 min-width: //设置最小宽度阈值 max-height //设置最大高度阈值 min-height //设置最小高度阈值
在使用上能够将它们做用在目标元素上,或者对目标元素有所限制的上级元素。
· 对于单位的认识
对于网页布局的单位,咱们不只要知道px就够了,还要知道其它几个比较经常使用的单位,特别是CSS3推出的一些新的度量单位。
em
em 是一种相对单位,它相对于父元素的字体大小。
em 经常使用于可缩放的字体需求中,好比在一个多行段落文本中,若是咱们设置行高为 line-height:16px
这一固定的像素值,那么一旦在缩放或者改变了文字的大小的状况下,字体会发生大小变化,可是行高的值却不会发生改变,永远为16px,若是咱们设置行高为 line-height:1em
那么此时行高的值即是一种相对的状况,它会随着文字大小的改变而改变。
由于em是相对于父元素的字体大小,因此在使用上咱们一般都是为 body
设置字体大小,这样即可以实现一改全改的效果。另外咱们还须要了解的是,浏览器默认的字体大小是16px,所以 1em 也就等于 16px。
rem
rem是一种相对单位,它相对于根元素 html
的字体大小。
利用这一特性,rem经常使用于移动端页面布局,下文中咱们会更详细的说到。
vh/vw
vh/vw都是相对于视口的单位,浏览器视口的区域就是经过 window.innerWidth
以及 window.innerHeigth
度量获得的范围。
浏览器会将整个视口的宽度或者高度划分为100等份,所以1vw或者1wh就是相对视口宽度或者高度的1%。例如浏览器视口的宽度是1920,那么 1920/100 每等份即19.2px。
vh/vw 在使用上很相似与百分比,可是vh/vw也具备百分比不具备的特性,那就是相对于视口,例如当父级元素不具备尺寸的时候,百分比便没法产生做用,可是相对于视口的vh/vw则能够。
vh/vw 还能够应用在一个页面上有不少垂直排列的区块,并且每一个区块的高度都是当前浏览器显示区域高度的状况下。
vmin / vmax
vmin / vmax 也是相对于视口的单位,可是vmin会根据视口宽高最小的那个为基准,而后分为100等份,而vmax 则会以视口宽高最大的那个一个为基准,而后分为100等份。
在了解了以上的基本知识后,我会根据一个现成的示例去解读混合方式的使用实例,这里我就以手机新浪网为例。
首先打开手机新浪网:https://sina.cn/
,在chrome下按 F12
,从上至下观察,咱们能够看到,新浪手机版页面的head中,经过meta标签对viewport的尺寸以及缩放进行了调整,再大体的看下页面内容咱们能够看出手机新浪网上很好的运用了H5新增的语义化标签,例如:
section : 定义每一个区域 details : 设置display:none隐藏,来表述对区域内容或做用的声明 mark : 标记内容,好比广告等。 nav : 用做导航 aside : 用于表示与页面主内容松散相关的内容,常常用于侧边栏、广告、友情连接、引文以及导航元素等。 header : 定义头部区域 footer : 定义了网页的尾部,它主要包含联系方式、地址、备案信息等。
再从总体到细节,首先是banner区域,咱们会发现banner区域的HTML结构很简单,就是 div > a > img + mark
结构,并且img的宽度是100%即当前显示区域的100%,高度则是自动适应。
接着,咱们看手机版的头部,它位于banner的下面,主要由logo、两个按钮以及经常使用功能按钮(天气,登陆)等组成,整个布局的思路是左右结构,logo与两个切换按钮都是左浮动,而经常使用功能按钮则是采用右浮动。这样的好处就体现于在左右两个结构之间留下了足够多的空白区域。
再接着的即是导航区域,导航的按钮数量不少,可是结构依然很简单,就是 nav > a
结构,而且全部的 a
进行左浮动,由于 a
中的内容都是文字,因此每一个导航按钮的高度能够经过 line-height
进行控制,每一个按钮之间的间隔则用 padding
撑开,宽度则是根据一行要展现的按钮数量除以1,这里一行显示6个再考虑到间距,所以宽度都是15%,采用百分比单位,最后经过 white-space:nowrap
强制控制按钮内容不换行。
再往下即是焦点图区域,这个区域跟咱们日常编写焦点图基本类似,因此就不在赘述。
最后即是页面主要的资讯内容区域,经过控制台咱们能够获得内容区域的主要结构是 dl > dt + dd
而且 dl 应用了 display:flex
,因此dl中的dt与dd便会水平并排自动划分宽度排列。dt中的是新闻图片,而dd中则存放新闻标题以及icon,并且dd也应用了box特性,并经过如下CSS属性,设置其内容及子元素的水平以及垂直排列方式
-webkit-box-orient:vertical; // 设置内容或子元素为上下垂直排列 -webkit-box-pack:justify // 设置内容或子元素为两端排列
总的来讲,混合模式在使用上其优势在于技术上接近传统PC端页面的布局方式,而你所要作的只是对PC上的布局技术进行稍微的改变,可是其缺点也很明显那就是关键元素高宽和位置都不变,只有容器元素在作伸缩变换,因此对于混合模式下的布局,元素、图片、文字在设计的时候都 要知足如下特性:
·弹性的元素控件 ·自适应的图片尺寸 ·流式的文字展现
更直观的理解,能够看下图:
REM 是一种相对单位,它依据的是“根”节点的字体 (font-size) 的大小。
REM 是目前移动端页面布局经常使用的方式,它可使整个页面的全部元素都随着显示设备尺寸的变化而相应的调整本身的尺寸,从而加强页面对设备适配的灵活性,这种变化我称之为“页面的缩放”。
既然REM会让页面根据不一样的显示设备进行适配缩放,那么必然就会有一个 标准页面尺寸,就目前而言,整个前端开发界使用最多的标准页面尺寸则是根据iphone4或者 iPhone5为依据的 640px*1366px
,也有以iphone6为基准的750px。这个标准的页面尺寸,咱们能够将其定义为1,若是当前的显示设备尺寸小于标准页面尺寸(640px或者750px)那么便让页面尺寸缩小,使其小于1。而当显示设备尺寸大于标准页面尺寸,咱们便可以作一些其它的适配,也能够将页面整个居中显示在显示设备中而后不进行任何缩放操做。
经过上述,咱们能够知道两个关键点,一是页面的缩放,这个咱们等下会说到,二就是采用rem为单位进行页面布局,实际上rem布局与px布局并无什么本质的区别,这个咱们能够代入实例去理解,好比如今 html
的 font-size
的大小是100px,即 1rem = 100px,若是如今页面中要放入一个200*200的盒子,那么按照等比关系,即:
div{ width:2rem; height:2rem; background:gray; }
除了将rem与px结合起来进行理解rem布局的原理,淘宝的前端工程师也提出了另外一种理解方式,这种方式的优势在于能够向后与 vw/vh 进行兼容理解,首先将页面划分为100分,每一份的宽度为(n)px,设定1rem = 10n,若是基准页面是640px的话,那么每份即6.4px 而 1rem = 64px。若是如今有一个 200px * 200px 的盒子,那么按照rem与px的等比关系,即:
div{ width:3.125rem; height:3.125rem; background:gray; }
最后咱们谈谈 REM 实现的页面缩放适配原理, rem 是依据 html
标记的 font-size
大小的相对单位,对于使用rem为单位的页面,在被载入到显示设备显示的时候,会根据显示设备的尺寸,而后对应的修改html标签的font-size值,这样即可以一处修改,整个页面内容都会发生改变,即实现根据设备尺寸进行缩放的效果。
REM方式进行移动端布局的原理都是相同的,可是不一样的在与对于设备尺寸的检测上,就目前而言分为两种,一种是经过CSS meida查询,另外一种则是经过JS检测。
响应式方式就是经过 CSS media 对显示设备进行媒体查询来改变rem与px的对应关系。
下面我贴出我己工做中使用到的移动端媒体查询规则:
@media screen and (min-width:320px) and (max-width:359px) { html { font-size: 50px; } } @media screen and (min-width:360px) and (max-width:374px) { html { font-size: 56.25px; } } @media screen and (min-width:375px) and (max-width:383px) { html { font-size: 58.59375px; } } @media screen and (min-width:384px) and (max-width:399px) { html { font-size: 60px; } } @media screen and (min-width:400px) and (max-width:413px) { html { font-size: 62.5px; } } @media screen and (min-width:414px) and (max-width:431px) { html { font-size: 64.6875px; } } @media screen and (min-width:432px) and (max-width:479px) { html { font-size: 67.5px; } } @media screen and (min-width:480px) and (max-width:539px) { html { font-size: 75px; } } @media screen and (min-width:540px) and (max-width:639px) { html { font-size: 84.375px; } } @media screen and (min-width:640px) { html { font-size: 100px; } body { max-width: 640px !important; margin: 0px auto !important; } }
在上面这段CSS媒体查询代码中,咱们以一个640px宽度的设计稿为基准的页面尺寸,并设定 html
标记的 font-size
值为100px,而后检测载入当前页面的显示设备尺寸,对应的改变font-size的值,最后再进行相应的缩放适配显示页面,当显示设备尺寸大于基准页面尺寸时则居中显示在显示设备中。
响应式REM布局的优势在于能够根据设计稿的特色,自定义的对某些设备进行单独适配,而缺点是检测规则固定不可变,这一点相比于“JS自动换算”更为明显。
根绝响应式方式的REM思路,咱们就能够很简单的经过JS代码写出相应的JS换算方式。
代码以下:
(function(win,doc){ var timer = null, html = doc.documentElement, baseWidth = html.dataset.basewidth*1 || 640, metaEl = document.querySelector('meta[name="viewport"]'), event = 'onorientationchange' in win ? 'onorientationchange' : 'resize'; if(!metaEl){ metaEl = document.createElement('meta'); metaEl.setAttribute('name','viewport'); metaEl.setAttribute('content','initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0'); html.firstElementChild.appendChild(metaEl); } function layoutCalc(){ var width = html.getBoundingClientRect().width, ratio = width / baseWidth * 100, devicePixelRatio = window.devicePixelRatio, rem = ratio < 100 ? ratio < 50 ? 50 : ratio : 100; if(!/\.\d+/.test(devicePixelRatio.toString())){ html.dataset.dpr = devicePixelRatio; } html.style.fontSize = rem + 'px'; } win.addEventListener(event,function(){ clearTimeout(timer); timer = setTimeout(layoutCalc,300); },false); win.addEventListener('pageShow',function(e){ if(e.persisted){ clearTimeout(timer); timer = setTimeout(layoutCalc,300); } },false); layoutCalc(); }(window,document));
功能说明:
· 自定义基准页面尺寸
经过为 html 标签添加 data-basewidth
属性来自定义指定基准页面的尺寸。
示例:
<html data-basewidth="750" > </html>
· 定义页面内容的字体大小
对于一些符合标准的dpr值(只要是整数,例如:1,2,3),都会为 html
标签再附加一个 data-dpr
属性,而后开发者即可以根据这个属性为条件,实如今不一样dpr状况下,对内容字体的大小的调整。
示例代码:
html[data-dpr="1"] .dpr-text{ font-size:12px; } html[data-dpr="2"] .dpr-text{ font-size:24px; } html[data-dpr="3"] .dpr-text{ font-size:36px; }
<p class="dpr-text">测试文字</p>
相比“响应式方式”JS自动换算无需添加规则,适合于各种型的显示设备。
一样是“缩放” REM方式在缩放的时候,会改变元素的尺寸,而下面要提到的缩放方式,并不会改变元素的原有尺寸,能够理解成只是在视觉上将内容或者页面缩放至与当前显示设备相匹配的尺寸。
这种缩放方式,也能够分为两种类型:
· 经过CSS3的transform对元素进行缩放。 · 对viewport进行缩放。
首先贴出具体的代码(我已经作好注释):
function pageScale(opt) { var ua = navigator.userAgent, wp = ua.match(/Windows Phone ([\d.]+)/), android = ua.match(/(Android);?[\s\/]+([\d.]+)?/), dom = document.querySelectorAll(opt.selector), // 获取要缩放的DOM,能够多个。 dw = document.documentElement.clientWidth, // 获取当前显示设备的宽度 dh = document.documentElement.clientHeight, // 获取当前显示设备的高度 pw = opt.width || 320, //获取设计稿的最小尺寸 - 宽度 ph = opt.height || 568, // 获取设计稿的最小尺寸 - 高度 mode = opt.mode || 'cover', // 获取显示模式 origin = opt.origin || 'left top 0', // 设置缩放中心点 ratio = 0, // 定义比值 i = dom.length; // 获取要调整DOM的个数 // 根据模式的不一样,从而生成响应的比值,总的来讲contain模式只关注宽高中最小的那个。 if (mode == "contain") { if (pw > ph) { ratio = dw / pw; } else { ratio = dh / ph; } } else if (mode == "cover") { // cover模式下,只关注宽高最大的那个。 if (pw < ph) { ratio = dw / pw; } else { ratio = dh / ph; } } else { ratio = dw / pw; } function calcScale(_mode, obj, num) { var _o = obj.style; _o.width = pw + "px"; _o.height = ph + "px"; _o.webkitTransformOrigin = origin; _o.transformOrigin = origin; _o.webkitTransform = "scale(" + num + ")"; _o.transform = "scale(" + num + ")"; // 兼容android 2.3.5系统下body高度不自动刷新的bug if (_mode == "auto" && android) { document.body.style.height = ph * num + "px"; } else if (_mode == "contain" || _mode == "cover") { //由于经过transform进行缩放,并不会致使DOM的重绘,所以就不会改变DOM的原有尺寸,因此在缩放的时候,仍是根绝原有尺寸进行缩放,从而致使缩放后位置发生偏移。从而须要定位进行位置的调整。 _o.position = "absolute"; _o.left = (dw - pw) / 2 + "px"; _o.top = (dh - ph) / 2 + "px"; _o.webkitTransformOrigin = "center center 0"; _o.transformOrigin = "center center 0"; // 阻止默认滑屏事件 if (wp) { document.body.style.msTouchAction = "none"; } else { document.ontouchmove = function (e) { e.preventDefault() } } } } // 循环DOM,依次执行缩放计算函数。 while (--i >= 0) { calcScale(mode, dom[i], ratio); } }
调用方式:
window.onload = window.onresize = function(){ pageScale({ selector : '.box', //模块的类名 mode : 'cover', // auto || contain || cover width : '320', //默认宽320px height : '568', //默认高568px origin : 'center center 0' //缩放中心点,可选,在contain和cover模式下无效,默认为"left top 0" }) }
这种CSS3缩放实现的移动端适配,是我在白树的一篇《pageResponse - 让H5适配移动设备全家》博客中看到的,而后我在其基础上按照本身的理解,进行了小小的修改。
总的来讲,想使用 白树 这种缩放的方式,第一步须要准备一个大并且高清的设计稿,好比按照iphone5的 640px*1136px
,而后调用方法时,要注意在参数中宽度与高度都要按照最小适配的那个尺寸为起始,例如我这里就是 320px*568px
。尤为要注意的是,若是页面中有插入图,须要将插入图的尺寸调整为 320*568。
具体HTML代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> <title>pageResponse</title> </head> <body> <div class="box"> <img src="demo.jpg" width="320" height="504" alt=""> </div> </body> </html>
viewport缩放,它的大体原理是取当前viewport的deviceWidth值与设计稿的宽进行相除,而后获得二者相差的比例值,再设置meta标签的initial-scale的为这个比例值,从而缩放整个viewport,这种方式的优势在于布局时,彻底能够按照PC端方式(能够用px为单位哦)进行布局,而且对于高版本的安卓,经过设置target-densitydpi属性 让其自动调整物理像素与逻辑像素的对应关系。
具体代码以下:
var phoneWidth = parseInt(window.screen.width); // 取得显示设备的逻辑像素,须要注意的是 screen.width方式 可能不许 var phoneScale = 680 / phoneWidth; var ua = navigator.userAgent; if (/Android (\d+\.\d+)/.test(ua)) { var version = parseFloat(RegExp.$1); // andriod 2.3到4.0 if ((version > 2.3) && (version < 3.0)) { document.write('<meta name="viewport" content="width=680, minimum-scale = ' + phoneScale + ', maximum-scale = ' + phoneScale + ',user-scalable=no,target-densitydpi=device-dpi">'); } else { // andriod 2.3一下那彻底不须要 谁特么还用那么老的东西?! document.write('<meta name="viewport" content="width=680, user-scalable=no, target-densitydpi=device-dpi">'); } // 其余系统 } else { document.write('<meta name="viewport" content="width=680, user-scalable=no, target-densitydpi=device-dpi">'); }
总的说,缩放方式实际上有一种缺陷,那就是ios系统会出现元素显示区域与实际元素所在区域有必定的偏移,影响文本、图片的查看和复制,微信中没法识别二维码。在没有文本复制和识别二维码的页面时能够用这种方法。
参考连接:
http://www.codeceo.com/article/font-size-web-design.html
https://github.com/amfe/lib-flexible
http://www.xiaoxiangzi.com/Programme/CSS/4298.html
下一篇:精通移动端布局 - 补充篇 - 【准备中】....
上一篇:精通移动端布局 - 概念篇 -