【目標】:前端開發移動端及H5時候,不須要再關心移動設備的大小,只須要按照固定設計稿的px值佈局!
【基礎】javascript
整體來講是將px經過預約義的配置,根據不一樣的dpr計算爲rem/vw,來實現不一樣屏幕大小的響應式伸縮css
css3的rem是基於根元素的字體大小計算的尺寸單位,因此經過改變html的font-size來實現rem的響應式佈局,例如使用css媒體查詢:html
html{font-size:10px} @media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}} @media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}}
但不一樣分辨率的屏幕計算轉換太複雜,媒體查詢不能兼顧全部的尺寸,因此能夠經過JS計算。先貼代碼:前端
var deviceWidth=document.documentElement.clientWidth; document.documentElement.style.fontSize =deviceWidth / bodyRemWidth + 'px';
例如設計稿基於iphone5的320px,deviceWidth爲320px,根元素的font-size基於100px,那body的width能夠寫爲3.2em;
當適配640px的屏幕時,deviceWidth爲640px,bodyRemWidth爲3.2rem,此時根元素的font-size計算爲200px;
deviceWidth就是viewport設置中的deviceWidth,viewport視圖提供佈局的窗口,包括移動端的顯示/縮放比例等設置;
須要設置mate的viewport使得顯示時的頁面寬度等於設備邏輯像素大小,移動端經常使用代碼:vue
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
deviceWidth=設備邏輯像素/(dpr * scale);
dpr爲固定值,高清屏通常爲dpr=2,因此scale=1/dpr,js動態設置scale:html5
var scale = 1 / devicePixelRatio; document.querySelector('meta[name="viewport"]') .setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
方式簡而言之就是,基於css3中Viewport相關vw、vh、vmin和vmax單位,將寬高的px計算爲vw/vh,而vmax/vmin老是指向那個最大/最小的屏幕長度java
var vw = window.innerWidth; var vh = window.innerHeight;
例如對於320px的設計稿,屏幕總長一直是100vw,因此比率是3.2,那css代碼須要將全部--px/3.2獲得**vm,
這樣很麻煩,因此使用postcss-px-to-viewport實現編譯時候的自動計算,還要配合postcss-write-svg,postcss-aspect-ratio-mini等插件解決Retina,1px等問題react
目前應用比較廣的是px2rem,隨着瀏覽器對viewport的支持,但將來趨勢是px2vm,用vm代替rem,但要兼容就大亂燉啥都要,,,
不少技術站都提供了兼容插件,好比postcss-cssnext, postcss-viewport-units, viewport-units-buggyfill。
不一樣的前端框架vue/react,配合webpack/grund等打包工具,能夠更高效的使用這些插件,完成移動端適配的配置工做。
【傳送門】
Amfe阿里前端團隊一直都對這方面的技術作了很是好的研究,還提供了開源的代碼:https://github.com/amfe/lib-f...
大漠寫的很是詳細的博客:使用Flexible實現手淘H5頁面的終端適配,還有進一步講vw的:再聊移動端頁面的適配,如何在Vue項目中使用vw實現移動端適配。向大牛獻上一份膝蓋~~~webpack
主要的插件都是基於PostCss的,千萬不要去百度PostCss,要否則從當前坑還沒爬出來,又會發現另外一個坑,,,css3
加油吧~少年~