你們在作移動端開發的時候若是隻用px+百分比的佈局方式而不作任何自適應處理的話就會出現這種狀況:按照750px設計圖寫頁面,若是設計圖給的字體大小是28px通常狀況下會除以2(這一步已經錯了),寫完之後放到iphone6s和iphone5測試就會發現原本在6s上感受蠻好的到了5上就變大了。而後心中萬馬奔騰……css
一、經過動態設置 viewport的 width 和 initial-scalehtml
二、經過動態設置跟元素Html的font-size 即 rem解決方案前端
meta標籤你們都很熟悉了,首先來看一下meta viewport 的6個屬性:css3
屬性名 | 解釋 |
---|---|
width | 設置viewport 的寬度,爲一個正整數,或字符串"width-device" |
initial-scale | 設置頁面的初始縮放值,爲一個數字,能夠帶小數 |
minimum-scale | 容許用戶的最小縮放值,爲一個數字,能夠帶小數 |
maximum-scale | 容許用戶的最大縮放值,爲一個數字,能夠帶小數 |
height | 設置viewport 的高度,這個屬性並不重要,不多使用 |
user-scalable | 是否容許用戶進行縮放,值爲"no"或"yes", no 表明不容許,yes表明容許 |
通常狀況下width的值設置爲width-device便可,即當前設備的屏幕寬度,咱們能夠經過window.screen.width獲取。因此要想在不一樣手機上自適應,咱們就要動態的改變initial-scale(初始縮放值),而且設置user-scalable=no禁止用戶手動縮放頁面。web
舉一個例子:若是設計師給的尺寸是750px的,如何把750px的設計圖等比縮放到咱們當前寬度的手機上呢?假如當前手機的屏幕寬度是剛好是750px,那initial-scale就等於1好了徹底不用縮放。假如當前的手機寬度是375px(iphone6/7/8),那豈不是要縮放一倍了(initial-scale=0.5),對的,縮放的倍數就等於當前手機屏幕寬度除以設計圖的寬度。若是設計師給的是640px寬的圖,針對不一樣的手機initial-scale的值是多少呢?(答案就在上一句)。app
因此initial-scale的值是要動態獲取的而後將meta標籤添加到header標籤裏面,這就要用js操做dom了(js基礎知識)。見下代碼示例:dom
<script> var _vwidth = window.screen.width; var _scale = _vwidth / 750; var _meta = document.createElement('meta'); _meta.setAttribute('name', 'viewport'); _meta.setAttribute('content', ' width = device - width , user - scalable = no , initial - scale = ' + _scale); document.getElementsByTagName('head')[0].appendChild(_meta); </script>
rem是指相對於根元素的字體大小的單位,它就是一個相對單位。看到rem你們必定會想起em單位,em是指相對於父元素的字體大小的單位。一個計算的規則是依賴根元素一個是依賴父元素計算。rem自適應原理就是動態改變根元素html的font-size大小。若是設置了html{font-size:20px;},那麼1rem=20px。如何動態改變html的fontSize呢,有兩種方式能夠實現。第一種是經過css3的媒體查詢,這樣的話在作開發前就要先統計有哪些主流的屏幕設備,而後去針對這些設備去作不一樣的兼容,以下示例:iphone
html { font - size: 20px; } @media only screen and (min - width: 375px) { html { font - size: 25px ! important; } } @media only screen and (min - width: 428px) { html { font - size: 26.75px ! important; } } @media only screen and (min - width: 481px) { html { font - size: 30px ! important; } } @media only screen and (min - width: 569px) { html { font - size: 35px ! important; } } @media only screen and (min - width: 641px) { html { font - size: 40px ! important; } }
到這裏確定有不少人會疑問是怎麼計算出不一樣分辨率下font-size的值的?其實這只是一個參考,若是設計圖尺寸是750,你能夠將750對應的fontSize設置爲100px,375對應fontSize就是50px以此類推。之因此在媒體查詢上面設置一個font-size : 20px;是由於當設備寬度小於375的時候都採用1rem=20px,固然這個值能夠更改的。以下示例:佈局
html { font - size: 20px; } @media only screen and (min - width: 750px) { html { font - size: 100px ! important; } } @media only screen and (min - width: 375px) { html { font - size: 50px ! important; } }
用css的方法是不能作全適配的,由於可能咱們沒有統計全或者將來還會出現更多不一樣分辨率的手機,可是用JS是能夠實現全適配。如下是經過js實現自適應,此時是針對750像素設計圖1rem=100px,即設計圖中字體大小爲28像素時,咱們要設置爲0.28rem。仍是很好換算的。若是設計圖給的是640px,只須要將結尾處的參數改爲640,640便可。測試
(function(designWidth, maxWidth) { var doc = document, win = window, docEl = doc.documentElement, remStyle = document.createElement("style"), tid; function refreshRem() { var width = docEl.getBoundingClientRect().width; maxWidth = maxWidth || 540; width > maxWidth && (width = maxWidth); var rem = width * 100 / designWidth; remStyle.innerHTML = "html{font-size:" + rem + "px;}" } if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(remStyle) } else { var wrap = doc.createElement("div"); wrap.appendChild(remStyle); doc.write(wrap.innerHTML); wrap = null } refreshRem(); win.addEventListener("resize", function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300) }, false); win.addEventListener("pageshow", function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300) } }, false); if (doc.readyState === "complete") { doc.body.style.fontSize = "16px" } else { doc.addEventListener("DOMContentLoaded", function(e) { doc.body.style.fontSize = "16px" }, false) } })(750, 750);
在項目中你們可根據實際狀況選擇,祝你們開發順利少加班!!!
歡迎掃描下方二維碼關注,這裏更多前端技術分享,讓咱們一塊兒成長 -- web前端週刊