移動端適配,目前本身經常使用的兩種 方案,參考如下兩篇好文css
方案一:使用lib-flexible包html
https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.htmlvue
使用flexible包方式,安裝 lib-flexible 包和 px2rem-loader包html5
npm install --save-dev lib-flexible px2rem-loader
在須要的js文件中頭部引入,若是是vue項目就引入到main.js中:webpack
import 'lib-flexible'
webpack配置loader,注意順序很重要,順序不對會出錯web
{ test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', {loader: 'px2rem-loader', options: { remUni: 75, remPrecision: 8, }}, {loader: 'postcss-loader', options: {plugins: [require("autoprefixer")("last 100 versions")]}} ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader?importLoaders=1', {loader: 'px2rem-loader', options: { remUni: 75, remPrecision: 8, }}, {loader: 'postcss-loader', options: {plugins: [require("autoprefixer")("last 100 versions")]}}, 'less-loader', ] },
這裏有個問題,在安卓下flexible.js源碼是所有按dpr=1來適配的,那天然是不行的,咱們修改一下源碼,改成按devicePixelRatio顯示npm
if (isIPhone) { // iOS下,對於2和3的屏,用2倍的方案,其他的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其餘設備下,仍舊使用1倍的方案 dpr = devicePixelRatio; //這裏將原來=1改成devicePixelRatio }
而後寫針對不一樣dpr下字體大小的視頻,這裏用less實現:sass
.font-dpr(@font-size) { font-size: @font-size; [data-dpr="1"] & { font-size: @font-size; } [data-dpr="2"] & { font-size: @font-size * 2; } // for mx3 [data-dpr="2.5"] & { font-size: @font-size * 2; } //for 小米note,for 小米mix [data-dpr="2.75"] & { font-size: @font-size * 2.2; } [data-dpr="3"] & { font-size: @font-size * 2.2; } // for 三星note4 ,三星s6 [data-dpr="4"] & { font-size: @font-size * 2; } }
使用的時候直接.font-dpr(20) 這樣嬸兒就能夠了。less
方案二:使用less或者sass等CSS 預處理語言寫適配方案post
http://www.javashuo.com/article/p-zvemticr-h.html
基準按照設計圖尺寸,可是缺點是不通用,不一樣頁面可能設計圖基準尺寸不一樣,致使在頁面本身的less文件中重置基準值也不生效,這裏想到了一個兼容的辦法,就是在本頁面的less中將傳入寬度或字體的數字進行換算。
這裏貼出個人mixin.less
// rem 單位換算:定爲 75px 只是方便運算,750px-75px、640-64px、1080px-108px,如此類推 @baseSize: 37.5; // 默認根元素大小基準值375,即設計圖尺寸爲寬375px,不一樣頁面設計圖尺寸不一樣,在頁面css頭部從新初始化並從新定義html根元素的font-size @baseDesign: 375; .font-size(@px) { font-size: (@px/@baseSize/2)*1rem; } .margin(@px) { margin: (@px/@baseSize/2)*1rem; } .margin-all(@a,@b,@c,@d) { margin: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem; } .padding(@px) { padding: (@px/@baseSize/2)*1rem; } .padding-all(@a,@b,@c,@d) { padding: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem; } .width(@px) { width: (@px/@baseSize/2)*1rem; } .height(@px) { height: (@px/@baseSize/2)*1rem; } .min-width(@px) { min-width: (@px/@baseSize/2)*1rem; } .max-width(@px) { max-width: (@px/@baseSize/2)*1rem; } .line-height(@px) { line-height: (@px/@baseSize/2)*1rem; } .margin-right(@px) { margin-right: (@px/@baseSize/2)*1rem; } .padding-right(@px) { padding-right: (@px/@baseSize/2)*1rem; } .margin-left(@px) { margin-left: (@px/@baseSize/2)*1rem; } .padding-left(@px) { padding-left: (@px/@baseSize/2)*1rem; } .margin-top(@px) { //margin: @px /(@baseDesign/2) * 100vw; margin-top: (@px/@baseSize/2)*1rem; } .padding-top(@px) { padding-top: (@px/@baseSize/2)*1rem; } .margin-bottom(@px) { margin-bottom: (@px/@baseSize/2)*1rem; } .padding-bottom(@px) { padding-bottom: (@px/@baseSize/2)*1rem; } .border(@px,@color) { position: relative; &::before{ content: ""; position: absolute; left: 0; top: 0; width: 200%; border:1px solid @color; color: @color; height: 200%; -webkit-transform-origin: left top; transform-origin: left top; -webkit-transform: scale(0.5); transform: scale(0.5); pointer-events: none; /* 防止點擊觸發 */ box-sizing: border-box; @media screen and (min-device-pixel-ratio:3),(-webkit-min-device-pixel-ratio:3){ width: 300%; height: 300%; -webkit-transform: scale(0.33); transform: scale(0.33); } } } .border-radius(@px) { border-radius: (@px/@baseSize/2)*1rem; } .border-width(@a,@b,@c,@d) { border-width: (@a/@baseSize/2)*1rem (@b/@baseSize/2)*1rem (@c/@baseSize/2)*1rem (@d/@baseSize/2)*1rem; } .top(@px){ top: (@px/@baseSize/2)*1rem; } .left(@px){ left: (@px/@baseSize/2)*1rem; } .right(@px){ right: (@px/@baseSize/2)*1rem; } .bottom(@px){ bottom: (@px/@baseSize/2)*1rem; } @imgPath: "../../assets/images/"; // 根元素大小使用 vw 單位 html { font-size: (@baseSize/(@baseDesign / 2)) * 100vw; @media screen and (orientation: landscape) { font-size: (@baseSize/(@baseDesign / 2)) * 100vh; } // 同時,經過Media Queries 限制根元素最大最小值 @media screen and (max-width: 320px) { font-size: 64px; } //橫屏下ipad等平板font-size最大限制 /* @media screen and (min-width: 813px) { font-size: 108px; }*/ }
若是使用該mixin的頁面設計圖寬度爲其餘尺寸,好比320,則進行換算:
@base: 320; @convert: 375/@base; .info{ .width(56*@convert); .height(30*@convert); }
這樣進行轉換以後能夠保證頁面中顯示的尺寸是徹底跟圖片中的尺寸一致。
若是設計圖頁面是一個banner類型,這樣至關因而頁面橫屏,且高度很低,建議重置mixin中的html根元素字體設置,由vh改成vw,形如:
html{ width:100vw; height:100vh; @media screen and (orientation: landscape) { font-size: (@baseSize/(@baseDesign / 2)) * 100vw; } }