比較好用的移動端適配的兩種方案及flexible和px2rem-loader在webpack下的配置


移動端適配,目前自己常用的兩種 方案,參考以下兩篇好文

方案一:使用lib-flexible包

https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html

使用flexible包方式,安裝 lib-flexible 包和 px2rem-loader包

npm install --save-dev lib-flexible px2rem-loader

在需要的js文件中頭部引入,如果是vue項目就引入到main.js中:

import 'lib-flexible'

webpack配置loader,注意順序很重要,順序不對會出錯

{
                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顯示

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實現:

.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或者sass等CSS 預處理語言寫適配方案

https://juejin.im/post/5caaa230e51d452b672f9703#heading-7

基准按照設計圖尺寸,但是缺點是不通用,不同頁面可能設計圖基准尺寸不同,導致在頁面自己的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;
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM