移動(dòng)端和PC端適配采用的方案,之前做大屏的時(shí)候設(shè)計(jì)稿是以1920*1080的尺寸設(shè)計(jì)的司倚,考慮到市面上的顯示其尺寸包括寬為1360锌唾、1440、1600触徐、1660這幾個(gè)尺寸咪鲜,我在做適配的時(shí)候基本都是使用百分比和calc的方式做自適應(yīng),在PC端基本沒有問題锌介,實(shí)際的大屏分辨率也都是1920*1080的嗜诀,所以一直都沒有問題猾警,這次大屏客戶的屏幕是3840*2160的分辨率,是之前的2倍隆敢,顯示效果可想而知发皿,與設(shè)計(jì)相差太多,所以從新考慮了適配方案拂蝎,采用postcss-px2rem的方案
前提:項(xiàng)目是使用官網(wǎng)的方式創(chuàng)建的vue2.0版本的項(xiàng)目
這個(gè)方案主要分兩步:這兩步是完全獨(dú)立的過程但又互相影響
1穴墅、根據(jù)分辨率動(dòng)態(tài)設(shè)置html的字體大小温自;
2玄货、引入postcss-px2rem將css中的px轉(zhuǎn)成rem;
html設(shè)置字體大小
有兩種方式為根節(jié)點(diǎn)html動(dòng)態(tài)設(shè)置字體大小悼泌,
第一種:使用lib-flexible.js設(shè)置
這個(gè)插件是淘寶團(tuán)隊(duì)開發(fā)的松捉,主要應(yīng)用于移動(dòng)端,代碼中有一段限制了字體動(dòng)態(tài)設(shè)置的屏幕大小是540px馆里,也就是說大于540px之后html的字體大小就不變了隘世。
function refreshRem()
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
所以在移動(dòng)端可以直接引用這個(gè)文件
下載方式:執(zhí)行yarn add lib-flexible
引入方式:在main.js中通過import 'lib-flexible'
引入
計(jì)算規(guī)則:他會(huì)給html設(shè)置字體大小為當(dāng)前屏幕寬度除以10的大小,比如iphone手機(jī)的屏幕物理像素是375*667
鸠踪,那html的字體大小就是37.5px
丙者。
第二種:模仿lib-flexible自己寫一個(gè)
lib-flexible只適用于移動(dòng)端,所以PC端需要模仿flexible自己按需求寫一個(gè)营密,網(wǎng)上有很多這種代碼械媒,思路都是根據(jù)瀏覽器可視區(qū)的大小動(dòng)態(tài)設(shè)置根節(jié)點(diǎn)html的字體大小,我暫且把文件命名為rem.js
// 基礎(chǔ)字體大小
const baseValue = 75
// 可視區(qū)的大小评汰,移動(dòng)端是屏幕的寬度纷捞,PC端是瀏覽器可視區(qū)的寬度
let clientWidth = 0
// 設(shè)計(jì)稿的寬度
const designWidth = 1920
// 設(shè)置 rem 函數(shù)
function setRem () {
// 當(dāng)前頁面寬度相對(duì)于 1920寬的縮放比例,可根據(jù)自己需要修改键俱。
clientWidth = document.documentElement.clientWidth
const scale = clientWidth / designWidth
// 設(shè)置頁面根節(jié)點(diǎn)字體大欣夹濉(“Math.min(scale, 2)” 指最高放大比例為2,可根據(jù)實(shí)際業(yè)務(wù)需求調(diào)整)
document.documentElement.style.fontSize = baseValue * scale + 'px'
}
// 初始化
setRem()
// 改變窗口大小時(shí)重新設(shè)置 rem
window.onresize = function () {
setRem()
}
這種方式更適用于PC端编振,baseValue可以隨意調(diào)整,但要跟postcss插件配合使用
配置postcss-px2rem
把px轉(zhuǎn)換成rem的工具有兩個(gè)臭埋,一個(gè)是post-css2rem另一個(gè)是postcss-pxtorem踪央,兩個(gè)用哪個(gè)都行,但是我看postcss-px2rem五年沒有跟新了瓢阴,本著有新的不用舊的原則畅蹂,我把px2rem換成了pxtorem,具體有啥區(qū)別我也不知道荣恐,反正效果就是把px轉(zhuǎn)成rem液斜,結(jié)果都一樣
先說postcss-px2rem
下載方式: yarn add postcss-px2rem
配置方式:在跟目錄下新建vue.config.js文件累贤,復(fù)制下面代碼上去
// 引入等比適配插件
const px2rem = require('postcss-px2rem')
// 配置基本大小
const postcss = px2rem({
// 基準(zhǔn)大小 baseSize,需要和rem.js中相同
remUnit: 75
})
module.exports = {
lintOnSave:true,
css:{
loaderOptions:{
postcss:{
plugins:[postcss]
}
}
}
}
再說說postcss-pxtorem
下載方式: yarn add postcss-pxtorem@5.1.1
,我的項(xiàng)目執(zhí)行yarn add postcss-pxtorem
默認(rèn)下載的是6.0版本結(jié)果運(yùn)行不起來少漆,所以我降低了版本
配置方式:在跟目錄下新建postcss.config.js文件臼膏,復(fù)制下面代碼上去,或者在vue.config.js中像px2rem那么配置也是可以的
//在postcss.config.js中配置
module.exports = {
"plugins": {
"postcss-pxtorem": {
//換算基數(shù),默認(rèn)100示损,把根標(biāo)簽的font-size規(guī)定為1rem為50px,在設(shè)計(jì)稿上量出多少px直接在代碼中寫多少px
rootValue: 75,
//保留rem小數(shù)點(diǎn)多少位
unitPrecision: 5,
//存儲(chǔ)將被轉(zhuǎn)換的屬性列表渗磅,'!font-size' 即不對(duì)字體進(jìn)行rem轉(zhuǎn)換
propList: ['*', '!border', '!font-size'],
//要忽略并保留為px的選擇器,例如fs-xl類名检访,里面有關(guān)px的樣式將不被轉(zhuǎn)換始鱼,支持正則寫法。
selectorBlackList: ['.radius'],
replace: true,
//(布爾值)媒體查詢( @media screen 之類的)中不生效
mediaQuery: false,
//設(shè)置要替換的最小像素值脆贵,px小于12的不會(huì)被轉(zhuǎn)換
minPixelValue: 12,
//默認(rèn)值是一個(gè)空數(shù)組医清,這意味著禁用白名單并啟用所有屬性
//propWhiteList: [],
//黑名單
propBlackList: ['font-size'],
}
}
}
或者
//在vue.config.js中配置
// 引入等比適配插件
const pxtorem = require('postcss-pxtorem')
// 配置基本大小
const postcss = pxtorem({
//換算基數(shù),默認(rèn)100卖氨,把根標(biāo)簽的font-size規(guī)定為1rem為50px,在設(shè)計(jì)稿上量出多少px直接在代碼中寫多少px
rootValue: 75,
//保留rem小數(shù)點(diǎn)多少位
unitPrecision: 5,
//存儲(chǔ)將被轉(zhuǎn)換的屬性列表状勤,'!font-size' 即不對(duì)字體進(jìn)行rem轉(zhuǎn)換
propList: ['*', '!border', '!font-size'],
//要忽略并保留為px的選擇器,例如fs-xl類名双泪,里面有關(guān)px的樣式將不被轉(zhuǎn)換持搜,支持正則寫法。
// selectorBlackList: ['.radius'],
// 是否刪除px的原有樣式
replace: true,
//(布爾值)媒體查詢( @media screen 之類的)中不生效
mediaQuery: false,
//設(shè)置要替換的最小像素值焙矛,px小于12的不會(huì)被轉(zhuǎn)換
minPixelValue: 12,
//默認(rèn)值是一個(gè)空數(shù)組葫盼,這意味著禁用白名單并啟用所有屬性
// propWhiteList: [],
//黑名單
// propBlackList: ['font-size'],
})
// 使用等比適配插件
module.exports = {
lintOnSave: true,
css: {
loaderOptions: {
postcss: {
plugins: [
postcss
]
}
}
}
}
這兩個(gè)post插件的計(jì)算規(guī)則都是一樣的,remUnit和rootValue的性質(zhì)相同村斟,轉(zhuǎn)換規(guī)則就是將你頁面的樣式除以這個(gè)值贫导,比如你頁面的某個(gè)元素設(shè)置成寬度750px,那么除以這個(gè)值就會(huì)轉(zhuǎn)換成10rem蟆盹,這個(gè)值是不變的孩灯,不隨瀏覽器可視區(qū)的寬度變化而變化,在1920的顯示器上轉(zhuǎn)成10rem逾滥,在1360的顯示器上也轉(zhuǎn)成10rem
lib-flexible與postcss如何配合使用
所以postcss需要跟flexible配合使用,我們先定義幾個(gè)變量峰档,然后縷清這幾個(gè)變量之間的關(guān)系
clientWidth //屏幕的寬度
designWidth //設(shè)計(jì)稿的寬度
rootValue //postcss中配置的數(shù)值
baseValue //在自己編寫的rem.js文件中的基礎(chǔ)數(shù)值
以1920*1080尺寸的設(shè)計(jì)稿為例:假如頁面有一個(gè)填滿屏幕寬度的元素,元素的寬度就是designWidth
該元素通過postcss轉(zhuǎn)化后的rem大小:designWidth/rootvalue
寨昙,無論屏幕如何縮放讥巡,該值是固定的
既然該值是固定的,那么實(shí)現(xiàn)適配就是通過動(dòng)態(tài)改變html的字體大小實(shí)現(xiàn)的
首先計(jì)算縮放比舔哪,因?yàn)榛A(chǔ)是1920的尺寸欢顷,在其他尺寸的屏幕就需要等比放大或縮小
縮放比:scale = clientWidth / designWidth
縮放比就是實(shí)際的屏幕寬度除以設(shè)計(jì)稿的寬度,如果實(shí)際寬度就是1920捉蚤,那么scale就是1抬驴,即不縮放炼七;如果實(shí)際屏幕是3840,那么scale就是2布持,即放大一倍
字體大小設(shè)置:baseValue * scale
也就是clientWidth / designWidth * baseValue
字體大小與post轉(zhuǎn)化后的rem相乘就應(yīng)該等于clientWidth豌拙,所以
(clientWidth / designWidth * baseValue)*(designWidth/rootvalue) = clientWidth
最后你會(huì)發(fā)現(xiàn)baseValue/rootvalue = 1
,也就是相等,所以在實(shí)際設(shè)置中鳖链,使用上述rem.js的計(jì)算方式姆蘸,只要保證baseValue和rootvalue相等就可以了
如果上面的方法很難理解的話,有一種實(shí)踐出真知的方式
就是放到瀏覽器中測(cè)試一下芙委,比如我的設(shè)計(jì)稿是1920*1080的逞敷,那么我就把瀏覽器調(diào)到1920寬,然后看html的字體大小是多少灌侣,這個(gè)字體大小就是postcss中的rootValue的值推捐,我現(xiàn)在rem.js中代碼執(zhí)行完html設(shè)置的大小是75px,那么我postcss中的rootValue大小就應(yīng)該是75