做为一名刚接触移动端页面的孩子,总会遇到不少问题,如为何 head 那里要加 viewport meta
,为何背景图片要用 二倍图
等等。我相信也有不少人跟你说,加 viewport
是为了让页面不缩放,让页面在手机上能1:1显示
;用 二倍图
是由于 retina
屏1个像素被分为4个像素,因此模糊了,须要用大一倍的图片,让其显示正常。css
或许你哦了一声后也一直这么作,可是你事实上并不明白更细节的缘由。我也一直很困惑。所以查阅了很多资料,今天算是懵懵懂懂有点明白。站在巨人的肩膀上记录一下。html
先看个例子:git
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> <style> *{margin: 0; padding: 0;} .box1{width: 320px; height: 100px; background: red;} .box2{width: 980px; height: 100px; background: blue;} </style> </head> <body> <div class="box1"></div> <div class="box2"></div> </body> </html>
若是你用iphone(320x640)的手机打开如上页面,你会发现,box1只占据屏幕一部分,box2是满屏的。为何会这样?为何 320px 在手机上看到的不是满屏的呢。github
其实,因为历史的缘由,苹果创造了两个 viewport
,分别是 visual viewport
和 layout viewport
。web
拿 320x640 的 iphone 做示例:visual viewport
就是屏幕的宽度 320;layout viewport
则是apple创造出来的一个虚拟容器,并规定了其宽度为 980px。至关于在 320px 的视觉容器(visual viewport)中,实际上有一个看不见的有 980px 的布局窗口(layout viewport),例如当咱们的页面设置一个 div 的宽度为100%时,这个 div 的实际值为 980px 而不是320px。因此,上面的 320px 宽 box1只占据屏幕一部分,而 980px 宽的 box2 可以满屏。ajax
注:不一样浏览器的 layout viewport 设定的数值不同chrome
但这样同时带来不小的问题,不少专门为 iphone 设计的 320px 页面,都缩小了,这显然不是苹果但愿的结果,因而,viewport meta
标签诞生了。canvas
<meta name=”viewport” content=”width=device-width, initial-scale=1.0, user-scalable=no”/>
width 表示 layout viewport 宽度。initial-scale 表示初始时的缩放比例,user-scalable 表示禁止用户缩放。 这样,上面的 meta 就把 layout viewport 的宽度设置为了跟设备的宽度(visual viewport) 同样大小。从而解决了专门为 iphone 设计的网页在手机上正常浏览。这也是咱们为何如今作手机端页面,都会先加 viewport meta
标签的缘由了。浏览器
关于二倍图,如今有太多的文章都解释了,从 CSS pixels,device pixels,PPI 解释到 devicePixelRatio。这里就不把这些概念再说一遍了。可是不少文章在介绍 devicePixelRatio 时,都有条公式 devicePixelRatio = 屏幕物理像素/设备独立像素
,而后举例说明时,设备的独立像素都只说是 320px,但都没解释为何是 320px,这里依然是历史缘由。app
话说当年 iphone 流行的时候,太多太多为 iph
one 量身定制的网站都设置了 viewport:width=device-width
,而且按照宽度320px来设计网页,致使了其余浏览器为了兼容性,都把 layout viewport 设置为了 320px,因此才有 iphone4 的 640/320 = 2,才有了二倍图的由来。但事实上如今分辨率愈来愈大,很多设备已经到达3倍了,但二倍的图片还算能够接受。因此直到如今都还强调二倍图。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui" /> <meta name="format-detection" content="telephone=no, email=no" /> </head> <body> </body> </html>
这是我每次新建移动端页面时的默认模版,跟PC端的主要区别是多了两行 meta
,
html{-webkit-text-size-adjust: 100%; font-size: 62.5%;} body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input,button, textarea, p, blockquote, th, td, hr{margin: 0; padding: 0; -webkit-box-sizing: border-box;} body{font-family: "Helvetica Neue", Helvetica, STHeiTi, Arial, sans-serif, "Microsoft YaHei"; font-size: 14px; line-height: 1.5; overflow-x: hidden; -webkit-overflow-scrolling: touch;} article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary{display: block;} audio, canvas, progress, video{display: inline-block; vertical-align: baseline;} audio:not([controls]){display: none; height: 0;} [hidden], template{display: none;} svg:not(:root){overflow: hidden;} a{background: transparent; text-decoration: none; -webkit-tap-highlight-color: transparent;} a:active{outline: 0;} abbr[title]{border-bottom: 1px dotted;} b, strong{font-weight: bold;} dfn{font-style: italic;} mark{background: #ff0; color: #000;} small{font-size: 80%;} sub, sup{font-size: 75%; line-height: 0; position: relative; vertical-align: baseline;} sup{top: -0.5em;} sub{bottom: -0.25em;} img{border: 0;} hr{box-sizing: content-box; height: 0;} pre{overflow: auto; white-space: pre; white-space: pre-wrap; word-wrap: break-word;} code, kbd, pre, samp{font-family: monospace, monospace; font-size: 1em;} button, input, optgroup, select, textarea{color: inherit; font: inherit; margin: 0;} button{overflow: visible;} button, select{text-transform: none;} button, html input[type="button"], input[type="reset"], input[type="submit"]{-webkit-appearance: button; cursor: pointer;} button[disabled], html input[disabled]{cursor: default;} input{line-height: normal;} input[type="checkbox"], input[type="radio"]{box-sizing: border-box; padding: 0;} input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button{height: auto;} input[type="search"]{-webkit-appearance: textfield; -webkit-box-sizing: border-box; box-sizing: border-box;} input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration{-webkit-appearance: none;} fieldset{border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em;} legend{border: 0; padding: 0;} textarea{overflow: auto; resize: vertical;} optgroup{font-weight: bold;} table{border-collapse: collapse; border-spacing: 0;} td, th{padding: 0;} ul, ol{list-style: none outside none;} h1, h2, h3 {line-height: 2; font-weight: normal;} h1{font-size: 18px;} h2{font-size: 16px;} h3{ font-size: 14px;} input::-webkit-input-placeholder, textarea::-webkit-input-placeholder{color: #ccc;}
这里基本抄的 normalize,PC与移动端通用。之因此不用 rem
而改成 px
,是由于 chrome 对 rem 的渲染还有不足,故暂时不用它,详情可点击: http://note.sdo.com/u/634718107660171185/n/bBXuN~l1zG2a4M2DY000cr
若是说写手机页面最经常使用的技术是什么,我认为是 flex
,为了让内容自适应,等分,水平居中,垂直居中,咱们均可以直接使用 flex 解决,事实上,它的表现跟 table 相似。
但 flex 麻烦的一点是须要写点兼容,由于它在成长的过程当中,出现了不一样的规范定义,形成如今不一样系统对其支持的写法不同,故麻烦了一点,这里当成代码片断总结一下。
.parent{display: -webkit-box; display: -webkit-flex; display: flex;} .child{-webkit-box-flex: 1; -webkit-flex: 1; flex: 1;}
.parent{display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center;}
.parent{display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center;}
注1:上面 parent 表明父元素,child 表明子元素,水平垂直居中把上面的分别合并起来便可。 注2: 在有了 flex 以后,如今不少弹窗组件的结构也在发生着变化,之前遮罩层都是与弹窗分开的,如今在移动端,彻底能够直接嵌套起来,如: div.overlay>div.pop , 而后 overlay 层 position: fixed; top: 0; bottom: 0; left: 0; right: 0; pop 层做水平垂直居中便可
关于 zepto ,事实上,做为一名重构在工做上基本不用接触到,这里把本身以前使用它遇到的坑作下记录。
zepto 默认只加载 zepto
、event
、ajax
、form
、ie
模块,故不要妄想一使用zepto就想调用 tap
等事件。需加载相应模块编译才能够。
参考 https://github.com/madrobby/zepto 官网的编译说明。
注: 下载下来后在 `make` 文件里找到 `modules = (env['MODULES'] || 'zepto detect event ...').split(' ')` ,添加 `touch` ,参照上面官网说明编译便可。
这里有我基于 zepto 1.1.4 编译好的一份包含 touch 模块的 zepto.js 点击下载。
点透,就是在元素绑定 tap 事件,进行元素的隐藏或移动位置时,其底下的元素恰好绑定了 click 事件或有web响应的元素时,会触发底下元素的响应,造成 穿透
同样的效果,咱们也称之为 点透
。
在使用 zepto 的 tap 方法时,就会发生点透现象。
click
事件,用 tap
代替fastclick
: https://github.com/ftlabs/fastclickhttp://www.w3cplus.com/mobile/mobile-terminal-refactoring-create-page.html
http://www.w3cplus.com/mobile/mobile-terminal-refactoring-uniform-and-center.html
http://www.w3cplus.com/mobile/mobile-terminal-refactoring-icons.html
http://www.w3cplus.com/mobile/mobile-terminal-refactoring-scroll.html
http://hax.iteye.com/blog/978184
http://weizhifeng.net/viewports2.html
http://www.qianduan.net/mobile-webapp-develop-essential-knowledge.html
http://www.w3cplus.com/css/A-pixel-is-not-a-pixel-is-not-a-pixel.html