移動端切圖備忘

做爲一名剛接觸移動端頁面的孩子,總會遇到不少問題,如爲何 head 那裏要加 viewport meta,爲何背景圖片要用 二倍圖 等等。我相信也有不少人跟你說,加 viewport 是爲了讓頁面不縮放,讓頁面在手機上能1:1顯示
;用 二倍圖 是由於 retina 屏1個像素被分爲4個像素,因此模糊了,須要用大一倍的圖片,讓其顯示正常。css

或許你哦了一聲後也一直這麼作,可是你事實上並不明白更細節的緣由。我也一直很困惑。所以查閱了很多資料,今天算是懵懵懂懂有點明白。站在巨人的肩膀上記錄一下。html

爲何要加 viewport meta

先看個例子: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 viewportlayout viewportweb

拿 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

  1. Safari iPhone: 980px
  2. Opera: 850px
  3. Android WebKit: 800px
  4. Windows Phone 7: 1024px

但這樣同時帶來不小的問題,不少專門爲 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倍了,但二倍的圖片還算能夠接受。因此直到如今都還強調二倍圖。

HTML起始模版

<!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

css reset

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,爲了讓內容自適應,等分,水平居中,垂直居中,咱們均可以直接使用 flex 解決,事實上,它的表現跟 table 相似。
但 flex 麻煩的一點是須要寫點兼容,由於它在成長的過程當中,出現了不一樣的規範定義,形成如今不一樣系統對其支持的寫法不同,故麻煩了一點,這裏當成代碼片斷總結一下。

1. 等分

.parent{display: -webkit-box; display: -webkit-flex; display: flex;}
.child{-webkit-box-flex: 1; -webkit-flex: 1; flex: 1;}

2. 水平居中

.parent{display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; justify-content: center;}

3. 垂直居中

.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.js

關於 zepto ,事實上,做爲一名重構在工做上基本不用接觸到,這裏把本身以前使用它遇到的坑作下記錄。

1. zepto 打包

zepto 默認只加載 zeptoeventajaxformie 模塊,故不要妄想一使用zepto就想調用 tap等事件。需加載相應模塊編譯才能夠。
參考 https://github.com/madrobby/zepto 官網的編譯說明。

注: 下載下來後在 `make` 文件裏找到 `modules = (env['MODULES'] || 'zepto detect event ...').split(' ')` ,添加 `touch` ,參照上面官網說明編譯便可。

這裏有我基於 zepto 1.1.4 編譯好的一份包含 touch 模塊的 zepto.js 點擊下載

2. 點透修復

點透,就是在元素綁定 tap 事件,進行元素的隱藏或移動位置時,其底下的元素恰好綁定了 click 事件或有web響應的元素時,會觸發底下元素的響應,造成 穿透 同樣的效果,咱們也稱之爲 點透
在使用 zepto 的 tap 方法時,就會發生點透現象。

解決方法:

  1. 不要使用 click 事件,用 tap 代替
  2. 使用 fastclickhttps://github.com/ftlabs/fastclick

未完待續...

參考文章

http://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

相關文章
相關標籤/搜索