web前端開發人員如何才能開發出適配每一個終端的wap頁面呢?若是還有點迷茫不知所措,下面的文章但願可能給你幫助,同時也能夠加深本身的記憶,有欠缺錯誤的地方,歡迎評論指出,相互學習。css
備註:(不討論百分比佈局方式)
若是有點心急的話能夠直接跳到第5步,欲知其原理還得慢慢來
複製代碼
首先,在解決問題以前,咱們先了解一下熟悉一些有趣的概念,幫助咱們更深的理解解決辦法哦!html
一、像素前端
什麼是像素?
像素是web頁面佈局的基礎,估計咱們每一個前端開發人員都離不開,那麼到底什麼纔是一個像素呢?可能你們會和我同樣有點質疑,是的平時天天都在寫,可是究竟是指什麼呢?
像素:就是計算機屏幕所能顯示一種特定顏色的最小區域。
在web前端開發領域,像素有如下兩種含義:
一、設備像素(物理像素):設備屏幕的物理像素,對於任何設備來說物理像素的數量是固定不變的。
二、設備獨立像素(也稱密度無關像素,虛擬像素):能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(好比說CSS像素),而後由相關係統轉換爲物理像素。
CSS像素(虛擬像素):這是一個抽象的像素概念,它是爲web開發者創造的。
複製代碼
設備 | 年份 | 尺寸 | 像素 | 點數 |
---|---|---|---|---|
iPhone4S | 2011年 | 3.5 | 640*960 | 320*480 |
iPhone5S | 2013年 | 4.0 | 640*1136 | 320*568 |
iPhone6 | 2014年 | 4.7 | 750*1334 | 375*667 |
iPhone6S Plus | 2015年 | 5.5 | 1242*2208 | 414*736 |
備註:此表所列舉的像素即爲設備像素(物理像素)git
二、屏幕密度github
指一個設備表面上存在的像素數量,它一般以每英寸有多少像素來計算(PPI)。
複製代碼
三、設備像素比web
簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係。它的值能夠按下面的公式計算獲得:
設備像素比(DPR) = 設備像素個數 / 理想視口CSS像素個數(device-width)
在JavaScript中,能夠經過 window.devicePixelRatio 獲取到當前設備的dpr
複製代碼
舉例:iPhone6的設備寬度和高度爲375pt * 667pt,能夠理解爲設備的獨立像素;而其dpr爲2(window.devicePixelRatio ),根據上面公式,咱們能夠很輕鬆得知其物理像素(設備像素)爲750pt * 1334pt。瀏覽器
四、視口(viewport)app
佈局視口:移動端CSS佈局的依據視口,即CSS佈局會根據佈局視口來計算
能夠經過如下JavaScript代碼獲取佈局視口的寬度和高度:
document.documentElement.clientWidth;
document.documentElement.clientHeight;
可視視口:用戶正在看到網站的區域
理想視口:定義了理想視口的寬度,好比對於iphone6來說,理想視口是375*667。
可是最終做用的仍是佈局視口,由於咱們的css是依據佈局視口計算的,
因此你能夠這樣理解理想視口:理想的佈局視口。
下面這段代碼能夠告訴手機瀏覽器要把佈局視口設爲理想視口:
<meta name="viewport" content="width=device-width" />
複製代碼
打起精神咯,講了這麼多開始進入正題咯...此時能夠來一條華麗的風格線iphone
五、基本定義瞭解以後開始寫代碼了,邊寫代碼邊打開調試模式,對照看可能理解更深入。以iPhone6設備爲例子(若是下面出現的術語有疑問能夠返回來繼續瀏覽)佈局
立刻開始解決問題嘍!
前情概要:iPhone6的設備寬度和高度爲375pt * 667pt,能夠理解爲設備的獨立像素;
而其dpr爲2,根據上面公式,咱們能夠很輕鬆得知其物理像素(設備像素)爲750pt * 1334pt。
複製代碼
a、建立HTML頁面,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>適配移動終端</title>
<style>
/* 初始化樣式 */
*{padding: 0;margin: 0}
.box{width: 375px;height: 375px;background: blanchedalmond}
</style>
</head>
<body>
<div class="box"></div>
<script>
window.onload = function () {
const screenWidth = document.body.clientWidth;
console.log("window.devicePixelRatio "+window.devicePixelRatio);
console.log("document.body.clientWidth的值爲 " + screenWidth);
}
</script>
</body>
</html>
複製代碼
打開調試器,查看設備像素比=2;佈局視口的寬度=980px
查看body的寬度:980px,爲佈局視口的寬度
查看box元素的寬度:375px
此時,爲了讓box元素的寬度佔滿屏幕,咱們須要將box的寬度設置爲多少呢?本身能夠動手操做一下 . . . . ...
最後.box{width:980px;height:980px},以下圖所示
緣由:
980px是佈局視口,經過document.documentElement.clientWidth得到,
而咱們平時寫的css樣式則是相對於佈局視口操做的,
因此,可是當佈局視口發生變化的時候咱們須要手動改頁面中元素的尺寸,
複製代碼
那麼有沒有簡單的辦法呢或者可優化的地方呢?
繼續:
b、在該HTML頁面中加入
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
複製代碼
這行代碼你們必定很熟悉,移動端開發通常都要加,加入這行代碼的意思是什麼呢?可讓佈局視口的寬度等於理想視口的寬度,頁面的初始縮放比例以及最大縮放比例都爲1,且不容許用戶對頁面進行縮放操做
這樣佈局視口和設備的寬度同樣了,都是375px;可是頁面元素box上一步設置的大小是980px因此已經超出了當前屏幕出現了滾動條,要讓該元素全屏顯示須要修改box樣式將寬度改爲375px; 可是仍是同樣的問題,當設備變成了一下設備甚至更多,以下:
設備 | 設備寬度 |
---|---|
iPhone5S | 320*568 |
iPhone6 | 375*667 |
iPhone6S Plus | 414*736 |
... | ... |
還有不少的安卓手機
寬度仍是會改變,應該繼續作些什麼呢?
叮咚!接着就要給你們推薦一個牛通常的存在移動端適配flexible方案
下載連接中的js,同時引入到咱們的HTML頁面中。 看看是否是解決問題了,無論在iPhone五、iPhone六、iPhone6S Plus...各類設備下.box{width:10rem}都能讓該元素寬度顯示全屏幕,那這個JS到底作了些什麼操做呢?
在這裏先要插播一個單位rem,相信你們都很熟悉, rem 是相對於根元素<html>的font-size來作計算。
而在這個方案中使用rem單位,是能輕易的根據<html>的font-size計算出元素的盒模型大小。
複製代碼
那麼應該怎樣換算成rem呢?
上圖中:根元素HTML字體大小爲37.5px
那麼在該實例中 1rem = 37.5px
同理:
若是根元素HTML字體大小爲75px
那麼在該實例中 1rem = 75px
那麼若是一個頁面根元素(html)字體大小設置爲41.4px,那麼該頁面中有一個元素寬度是270px,轉化成rem是多少呢?
結
果
是
1rem = 41.4px
270px / 41.4px = 6.52rem(約等於)
移動端適配flexible方案主要作了些什麼呢?
目的:適配移動終端 當咱們將頁面的字體設置爲 佈局視口/10的時候,想要讓一個元素全屏顯示寬度,就都是設置10rem
下面咱們來本身算一下:
設置 | 佈局視口 | 根目錄字體 大小 | 頁面中某元素寬度100% |
---|---|---|---|
iphone5 | 320px | 32px | 1rem = 32px 320px/32px = 10rem |
iphone6 | 375px | 37.5px | 1rem = 37.5px 375px/37.5px = 10rem |
iphone6Ps | 414px | 41.4px | 1rem = 41.4px 414px/41.4px = 10rem |
... | ... | ... | ... |
解析:佈局視口 (375px)/ 根元素字體大小(37.5px) = 10rem
複製代碼
附上flexible.js(細細品味)
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded',
setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
複製代碼
但願你能夠本身作一個實例,畢竟書上得來終覺淺,絕知此事要躬行(對某個元素疑問的能夠返回去本身看或者搜索更多的內容,幫助理解)。
你能夠找個現有的PSD設計圖開始練習,尺寸爲750px*1300px(其實和PSD的大小是沒有關係的)
將PSD的尺寸當成佈局視口就能夠了,固然根元素字體就是佈局視口尺寸/10
複製代碼
怎麼樣了?加油,你是最棒的,其實解決這個不僅是這種辦法,你們能夠在理解都基礎上開始各類嘗試,好比根據dpr的值改變佈局視口的大小等等...
總結:其實下載移動端適配flexible方案的js,引入js就能夠解決適配問題,前面囉囉嗦嗦的只是爲了清楚爲何這樣作能夠解決問題,但願能有所幫助。本身理解可能也有些偏差,不足之處望指正。
(參考連接:github.com/amfe/articl…)