如上圖,Native app
是使用原生開發的 app, 優勢是性能更好,還能調用系統的 api ,可是發佈 app 流程繁瑣,並且不跨平臺。css
而Web app
, 優勢是跨平臺,修改方便,缺點是不能調用原生的 api, 並且用戶體驗不如原生 app, 好。html
而Hybrid app
, 結合了上面兩個的優勢,能夠說是很 nice。android
又稱爲設備獨立像素、邏輯像素。CSS中使用的一個抽象的概念,單位是 px
。ios
值是相對的,並非絕對的,根據 dpr
來肯定一個 CSS 像素表明幾個物理像素,還有一些狀況,例如用戶縮放的時候,,dpr
也會跟着變爲 2, 此時一個 CSS 像素表明兩個物理像素。css3
注意: 電腦當中的一個設備像素通常是等於一個 CSS 像素。因此咱們在 PS 當中的切圖大小,通常也表明物理像素表示的大小。web
又稱爲物理像素,任何設備屏幕的物理像素的數量自出場開始就是固定不變的,單位是 pt
(點)。一個物理像素即屏幕上一個發光的點。物理像素單個點的大小由廠商決定,大小不固定。api
指的是屏幕對角線的長度,單位爲英寸,注意英寸是長度單位,不是面積單位。1英寸(inch)=2.54釐米(cm)。瀏覽器
屏幕尺寸=屏幕斜邊的像素/PPI。app
單位面積上(英寸)像素(設備像素)的數量。它是一個定值,是一個固定的參數。PPI=屏幕斜邊的像素/屏幕尺寸。以下:dom
因此要提升 PPI的話,須要增長水平和豎直方向的像素點數量。所以,同一尺寸(inch)下,PPI提升了一倍,那像素會變爲原來的4倍,也就是所 PPI 增長 N 倍,單位面積上的像素點的數量變爲原來的 N^N 倍,以下圖。查詢不一樣設備的 ppi
PPI 的值越高,表明在必定尺寸的屏幕上像素數量越多,屏幕越清晰。以下同一張圖片。
但同時,因爲單位面積(英寸)並無變,因爲 PPI 的變大,對應的物理像素點會縮小。和上面的物理像素點的規律相反,PPI 增長 N 倍,單位面積上的像素點的大小將變爲原來的 1 / N^N 倍。以下圖:
同時對於一張圖像,放到比當前 PPI 大的設備上時,也將按照上面的比例變小。例如一個放到一個 PPI 爲本身的 2 倍的設備上時,圖像將縮小四倍,以下圖。
可是在實際當中咱們更但願圖片保持原有大小,而且最好是也不變模糊,保持原有的清晰度。對於上面的狀況,解決方案是設備的 DPR 須要是原來設備的 2 倍,即便一個 CSS 像素須要表明的物理像素點須要變爲原來的 2 倍,這就保持了圖像的大小未發生改變,同時圖片的分辨率也須要變爲原來的兩倍,這樣就保持圖像的清晰度未發生改變。
DPR=物理像素/css像素。獲取:window.devicePixelRatio
。查詢1。查詢2
它的本質是指一個 CSS 像素表明幾個 物理像素。它的意義是爲了讓圖像可以早高清屏上顯示。
其實上當像素比超過 2 後,肉眼是識別不出來的。
只針對 PC 端的頁面直接放到移動端的狀況的話,默認會進行縮小。首先是由於移動端的像素點通常比 PC 端更加的密集,因此相應的物理像素點都會變得很小,同時在這個縮放的基礎之上,瀏覽器還會根據狀況繼續進行縮小。縮放比=物理像素(即設備像素)/ 視口寬度(html 的寬度,默認是 980px, 用document.documentElement.clientWidth
方法獲取)。因此在移動端開發的時候,咱們須要正確的設置 ViewPort的值。
典型的 ViewPort 的設置值爲下面這樣:
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
device-width
(設備的實際寬度--即設備的 css 像素)。須要注意的是,在移動端,若是不限制縮放,那麼爲了保證頁面所有可見,會對頁面總體進行縮放, 縮放的計算方式爲: 縮放比(initial-scale)=css像素(設備css像素)/viewport寬度(html寬度)。
initial-scale = 1
,能夠達到和 width=device-width
, 同樣的效果。若是都設置了,取二者的最大值。
通常當咱們都禁止用戶進行縮放,以下:
minimum-scale=1,maximum-scale=1,user-scalable=no
通常根據上面的公式,咱們能夠經過設置縮放比,動態的設置 viewport 的寬度。
meta
標籤禁止識別電話與郵箱(可是郵箱沒效果) <meta name="format-detection" content="telephone=no,email=no" /> 設置添加到主屏後的標題(ios) <meta name="apple-mobile-web-app-title" content="標題"> 添加到主屏幕後,全屏顯示,刪除蘋果默認的工具欄和菜單欄(無用) <meta name="apple-mobile-web-app-capable" content="yes" /> 放在桌面上的logo <link rel="apple-touch-icon-precomposed" href="iphone_logo.png" /> 啓動時候的畫面(無用) <link rel="apple-touch-startup-image" href="logo_startup.png" /> 設置x5內核瀏覽器只能豎屏瀏覽(只有UC有效) <meta name="x5-orientation" content="portrait" /> 設置x5內核瀏覽器全屏瀏覽 <meta name="x5-fullscreen" content="true" /> 設置UC瀏覽器只能豎屏瀏覽 <meta name="screen-orientation" content="portrait"> 設置UC瀏覽器全屏瀏覽 <meta name="full-screen" content="yes"> 若是想屏蔽全部瀏覽器的橫屏的話,須要在後面陀螺儀那章節講
一、禁止用戶選中文字,安卓無效(在事件那章解決,包括長按的時候會出菜單,用阻止touchstart後的默認行爲搞定) -webkit-user-select: none; 二、禁止長按彈出系統菜單 -webkit-touch-callout: none; 三、去除android下a/button/input標籤被點擊時產生的邊框 & 去除ios下a標籤被點擊時產生的半透明灰色背景 -webkit-tap-highlight-color: rgba(0,0,0,0); 四、切換橫豎屏或者用戶本身經過瀏覽器設置的話,能夠改變字體的大小(須要給body下的全部元素) -webkit-text-size-adjust: 100%; 五、按鈕在ios下都是圓角 -webkit-appearance: none; //button與input都會有個默認背景 border-radius: 0; //input有個默認圓角 六、修改placeholder的樣式 input::-webkit-input-placeholder{ color:#000; //默認的樣式 } input:focus::-webkit-input-placeholder{ color:#f00; //點擊後的樣式 } 七、字體 ios 默認中文字體是Heiti SC 默認英文字體是Helvetica 默認數字字體是HelveticaNeue 無微軟雅黑字體 android 默認中文字體是Droidsansfallback 默認英文和數字字體是Droid Sans 無微軟雅黑字體 font-family: helvetica;
適配是爲了一版設計稿走天下,適配的範圍包括字體、寬高、間距、圖像
在熟悉瞭解了前面的概念以後,下面就來介紹移動端的適配幾種方式。
根據父級設置寬度。可是有時候百分比不太好算,並且計算的時候須要知道父級的高度。
viewport
縮放適配把全部機型的 css 像素設置成一致的,那麼切圖的時候只須要切一種尺寸的就能夠了。代碼以下
(function(){ //獲取css像素(viewport沒有縮放) var curWidth=document.documentElement.clientWidth; var targetWidth=375; // 最終尺寸 var scale=curWidth/targetWidth; // 縮放比 var view=document.getElementById('view'); view.content='initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+''; // 這樣設置了之後,全部設備上的 viewport 都爲 375了。 })();
注意這裏也須要將最大和最小縮放比設置爲和初始的值同樣,否則若是它們都仍是 1 的話,前面的就沒有效果了,由於如今仍是規定最大最小的縮放比爲 1。
缺點:由於如今在任何設備上的viewport的寬度都爲固定的寬度,例如 375 的圖片放到 大屏幕上,由於寬度是固定的,因此確定會變得模糊
DPR
縮放適配根據dpr的值,把視口進行縮放,縮放到物理像素,也就是把css像素的值設置成物理像素,讓全部的設備都變成一個css像素對應一個設備像素,方便切圖
(function(){ /* 375*2 750 320*2 640 375/?=750 => 375/750=2 1/dpr // 公式 320/scale=640 => scale=320/640 1/2 */ var meta=document.querySelector('meta[name="viewport"]'); var scale=1/window.devicePixelRatio; if(!meta){ //這個條件成立說明用戶沒有寫meta標籤,我須要建立一個 meta=document.createElement('meta'); meta.name='viewport'; meta.content='width=device-width,initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+''; document.head.appendChild(meta); }else{ meta.setAttribute('content','width=device-width,initial-scale='+scale+',user-scalable=no,minimum-scale='+scale+',maximum-scale='+scale+''); } })();
rem
適配rem 是相對於根節點(html
)的字體大小。
它的原理是把全部的設備都分紅相同的若干份,再計算元素寬度所佔的份數,開發的時候只須要使用一個特定的設備 而且使用rem 那麼在其餘設備上會自動出現相同的效果即自動適配(很神奇),而且設計稿須要以物理像素爲準來設計 例如分辨率寬爲 375 drp爲2,那麼實際針對該機型的設計搞應該爲750。
即經過媒體查詢,對全部範圍內的尺寸給定一個 html 根結點字體大小。可參考蘇寧易購。
(function(){ var html=document.documentElement; //html var width=html.clientWidth; //css像素 // 方式一 html.style.fontSize=width/16+'px'; //把屏幕分紅了16列,以iphone爲例得出一個列的值爲整數 // 方式二 html.style.fontSize= 16 * clientWidth / 375 + 'px'; // 以iphone6 爲基準,當大於 iphone6 的尺寸時,字體大小大於 16px, 同理小於時,字體小於 16px。 })();
相比於上面的普通方式,經典方式省掉了,根據設計稿量出的實際尺寸除以 dpr 這一步,直接將設計稿當中量出來的尺寸除以 100 而後單位爲 rem。下面依然以 iphone6 爲例。
(function(doc, win, designWidth) { const html = doc.documentElement; const refreshRem = () => { const clientWidth = html.clientWidth; if (clientWidth >= designWidth) { //給寬度一個最大值,若是設備的寬度已經超過設計稿的尺寸了,統一按一個值去算(傳的第三個參數) html.style.fontSize = '100px'; } else { html.style.fontSize = 100 * (clientWidth / designWidth) + 'px'; // 這種方式是咱們在切圖的時候不須要手動去除dpr, 已經幫咱們處理好來,可是咱們在計算的時候仍是必須使用1rem = 100px來計算 } }; //dom加載完的一個事件 doc.addEventListener('DOMContentLoaded', refreshRem); })(document, window, 750);
vw
適配vw 將頁面分爲 100 份,相關單位以下:
兼容性以下:
而且 vw、vh分別表明水平和豎直方向,和橫豎屏沒有關係,會自動根據橫豎屏來計算獲得每一份的寬度,如圖:
有兩種使用 vw 方式
通篇使用 vw, 和前面 rem 部分提到的 js 簡單部分差很少,只不過省略了計算每一份的過程,瀏覽器自動幫咱們計算 1vw 是多少。注意切圖的使用仍是要除以 dpr。能夠採用 scss 等 css 預處理語言來簡化這個過程。
經過 vw 設置根節點字體大小,頁面裏的尺寸依然使用rem。可是前提是你要知道頁面當中根節點的字體大小,根節點字體的大小的計算參考前面 rem 佈局部分的 js 經典方式。
在 ios 下面,若是頁面裏有一個固定定位(fixed)的元素以及一個 input 元素的時候,用戶但凡點擊input調出鍵盤的時候,固定定位元素就會不起做用。解決方式:
1px
問題在移動端 dpr, 每每是 2 及其以上,因此 1px 每每表明多個物理像素,這就是 1px 問題, 解決辦法:
1px = 1pt
section::after{ content: ''; position: absolute; left: 0; top: 0; border: 1px solid #000; box-sizing: border-box; width: 100%; height: 100%; transform-origin: 0 0; transform: scale(0.5); }