精通移动端布局

完整目录:

基本概念
    物理像素
    设备独立像素
    CSS 像素
    PPI的概念
    DPR的概念
    缩放的概念
    viewPort 的概念
    viewport 渲染流程
    Meta 标签说明

移动端布局实践
    混合方式
    REM 方式
        响应式
        JS自动换算
    缩放方式
        CSS3 缩放
        viewport 缩放

相关补充
    为什么需要meta标签?
    传统响应式布局与移动端响应式的区别
    移动端字体以及大小的设置
    移动端背景图缩放设置
    使用Sass提高px与rem转换效率
    通过Chrome进行真机调试
    weinre 远程调试


移动端布局实践

混合方式

混合方式实现的移动端布局实际上就是对PC端布局技术的组合使用,它主要包含以下技术:

  • 定位布局
  • 浮动布局
  • 可塑性布局
  • 百分比布局
  • 相对单位

将这些布局方法根据页面每个不同部分的特性进行组合使用,例如模态框,弹出层等可以采用定位方式,而页面元素的排版可以采用浮动布局,也可以使用具有可塑性的Flex布局方案,对于元素的尺寸可以采用百分比或者其它相对单位,而这便是我称之为“混合方式”的原因。
混合方式进行的移动端网页布局,所采用的技术通常都具有灵活、可伸缩、可塑等特点,甚至连使用的单位,最好都是相对单位,也只有这样才能满足屏幕尺寸多样性的移动设备。

对于混合布局技术,我首先要说几点我认为比较重要的基础知识点:

· 声明meta标签
通过meta标签来声明viewport是进行手机端页面开发的必须也是起始步骤

<meta name="viewport" content="width=device-width,maximum-scale=1,minimum-scale=1,user-scalable=no />

· 百分比计算公式
如果你在进行移动端网页布局中使用到了百分比单位,那么这个公式你一定要清楚

百分比 = 目标尺寸 / 上下文尺寸。

其中目标尺寸就是当前元素的尺寸,而上下文尺寸则是包含当前元素的父元素,通过 目标尺寸 / 上下文尺寸 便可以得到我们需要的百分比结果,另外个人建议百分比结果保留所有小数。

· 设置阀值
可伸缩的布局方案有一个本质特点就是会根绝显示设备的尺寸进行自适应调整,这一特性本身就是我们所期待的,但是在某些极端的环境下,比如过大或过小的屏幕下,某些元素尺寸也会变的过大或者过小,或者图片被严重拉伸,导致失真等,从而使显示效果变的很差,而下面的这些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 方式

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自动换算”更为明显。

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进行缩放。

CSS3 缩放

首先贴出具体的代码(我已经做好注释):

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 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值