前端開發,必然會遇到多端適應,在不一樣分辨率的設備上,擁有一樣的效果。常見的方法有媒體查詢、百分比、rem、vw/vh,開發人員在經常使用的px單位狀況下,怎麼運用上面的方法呢,請見正文。css
px, 是開發人員經常使用來進行開發的單位,寬、高、間隙等,可是你們想一下,應該清楚: px是跟經常使用的單位,好比釐米/米等固定單位是有區別的。html
咱們在pc端,設置文字16px,在移動端,可能就變得很小很小了。前端
爲了理清楚這個概念咱們首先介紹像素和視口的概念webpack
像素是網頁佈局的基礎,一像素表示設備能顯示的最小的單位,像素又分爲物理像素和CSS像素css3
物理像素和CSS像素又是怎麼轉換的呢,先看一下視口的概念web
視口分廣義和狹義,廣義是瀏覽器顯示內容的屏幕區域,狹義分下面幾種:佈局、視覺、理想npm
在pc網頁的狀況下,默認定義大小爲980px,若是在沒有設置viewport狀況下,pc頁面在移動端展現的話,會以默認大小爲基準,若是以默認大小進行顯示的話,在移動端會很模糊瀏覽器
表示瀏覽器看到的網站的區域,用戶能夠經過放大縮小來進行查看網頁裏面的內容,從而改變視覺視口的大小,至關於拿一個放大鏡進行觀察。所以,視覺這並不影響佈局視口的實際高度和寬度bash
能夠總結爲一句話,理想視口就是在給定的物理像素狀況下,最佳的佈局視口。換句話說,就是要獲取移動端的最佳佈局視口。iphone
爲了在移動端獲取最佳佈局視口,經常使用viewport標籤來進行控制
<meta id="viewport" name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1; user-scalable=no;">
複製代碼
主要屬性爲 content裏面的width,要適應移動端佈局,須要設置其爲device-width,通常表示分辨率寬,這樣設置就把移動端的佈局設置成理想視口了。
1 DPR = 物理像素/分辨率
複製代碼
若是在不縮放狀況下,1css 對應 1dpr
1 CSS像素 = 物理像素/分辨率
複製代碼
經過上面的viewport元標籤,咱們已經把佈局設置成理想視口時,1CSS像素能夠表示爲
1CSS = 物理像素/分辨率
複製代碼
在pc佈局視口下,通常爲980px,移動端以iphone6爲例,分辨率375 * 667 ,如今有一個750px * 1134px視覺稿,在pc端:
1CSS = 750 / 980 = 0.76px
複製代碼
在移動端:
1CSS = 750 / 375 = 2 px
複製代碼
很明顯移動端和PC端每CSS像素對應的物理像素,若是隻用一套px的CSS的做爲單位,這樣是沒法作到各端展現同樣的樣式。要想獲得同樣的效果,有下面幾種辦法。
若是一套樣式不行,那麼可否給每一種設備各一套不一樣的樣式來實現自適應的效果?
答案是確定的
使用@media媒體查詢能夠針對不一樣的媒體類型定義不一樣的樣式,特別是響應式頁面,能夠針對不一樣屏幕的大小,編寫多套樣式,從而達到自適應的效果。舉例來講:
@media screen and (max-width: 960px){
body{
background-color:#FF6699
}
}
@media screen and (max-width: 768px){
body{
background-color:#00FF66;
}
}
@media screen and (max-width: 550px){
body{
background-color:#6633FF;
}
}
@media screen and (max-width: 320px){
body{
background-color:#FFFF00;
}
}
複製代碼
媒體查詢的缺點也很明顯,若是在瀏覽器大小改變時,須要改變的樣式太多,那麼多套樣式代碼會很繁瑣。
除了用px結合媒體查詢實現響應式佈局外,咱們也能夠經過百分比單位 " % " 來實現響應式的效果。
好比當瀏覽器的寬度或者高度發生變化時,經過百分比單位,經過百分比單位可使得瀏覽器中的組件的寬和高隨着瀏覽器的變化而變化,從而實現響應式的效果。
css中的子元素中的百分比(%)究竟是誰的百分比?
子元素的height或width中使用百分比,是相對於子元素的直接父元素,width相對於父元素的width,height相對於父元素的height。
子元素的top和bottom若是設置百分比,則相對於直接非static定位(默認定位)的父元素的==高度==。
一樣,子元素的left和right若是設置百分比,則相對於直接非static定位(默認定位的)父元素的==寬度==。
子元素的padding若是設置百分比,不管是垂直方向或者是水平方向,==都相對於直接父親元素的width==,而與父元素的height==無關==。 margin跟padding同樣
rem單位不管嵌套層級如何,都只相對於瀏覽器的根元素(HTML元素)的font-size。默認狀況下,html元素的font-size爲16px,因此:
1 rem = 16px
複製代碼
能夠經過改變html font-size 來進行動態自適應
有個問題就是開發的時候,單位用rem,而設計師通常都是用px來設計,開發者用rem來開發,極爲不適應,雖然能夠 font-size進行轉換。
有個方案,是開發也用px,用webpack loader進行轉譯
npm install px2rem-loader
複製代碼
配置文件
module.exports = {
// ...
module: {
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'px2rem-loader',
// options here
options: {
remUni: 75,
remPrecision: 8
}
}]
}]
}
複製代碼
npm install postcss-loader
複製代碼
在webpack的plugin中:
var px2rem = require('postcss-px2rem');
module.exports = {
module: {
loaders: [
{
test: /\.css$/,
loader: "style-loader!css-loader!postcss-loader"
}
]
},
postcss: function() {
return [px2rem({remUnit: 75})];
}
}
複製代碼
在響應式佈局中,必須經過js來動態控制根元素font-size的大小。
css3中引入了一個新的單位vw/vh,與視圖窗口有關,vw表示相對於視圖窗口的寬度,vh表示相對於視圖窗口高度,除了vw和vh外,還有vmin和vmax兩個相關的單位。
單位 | 含義 |
---|---|
vw | 相對於視窗的寬度,視窗寬度是100vw |
vh | 相對於視窗的高度,視窗高度是100vh |
vmin | vw和vh中的較小值 |
vmax | vw和vh中的較大值 |
相關的轉換,好比 375 分辨率的設備
1px = (1/375)*100 vw
複製代碼
也能夠經過postcss的相應插件,預處理css作一個自動的轉換,能夠自動將px轉化成vw。
var defaults = {
viewportWidth: 320,
viewportHeight: 568,
unitPrecision: 5,
viewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false
};
複製代碼
經過指定視窗的寬度和高度,以及換算精度,就能將px轉化成vw。好比375
vw/vh 方案因瀏覽器兼容有問題,暫時只做瞭解,可不深刻學習.