前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >比较好用的移动端适配的两种方案及flexible和px2rem-loader在webpack下的配置

比较好用的移动端适配的两种方案及flexible和px2rem-loader在webpack下的配置

作者头像
蓓蕾心晴
发布2019-08-05 14:47:39
1.6K0
发布2019-08-05 14:47:39
举报
文章被收录于专栏:前端小叙

移动端适配,目前自己常用的两种 方案,参考以下两篇好文

方案一:使用lib-flexible包

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

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

代码语言:javascript
复制
npm install --save-dev lib-flexible px2rem-loader

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

代码语言:javascript
复制
import 'lib-flexible'

webpack配置loader,注意顺序很重要,顺序不对会出错

代码语言:javascript
复制
{
                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显示

代码语言:javascript
复制
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
        }

然后写针对不同dsp下字体大小的视频,这里用less实现:

代码语言:javascript
复制
.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

代码语言:javascript
复制
// 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,则进行换算:

代码语言:javascript
复制
@base: 320;
@convert: 375/@base;

.info{
    .width(56*@convert);
    .height(30*@convert);
}

这样进行转换之后可以保证页面中显示的尺寸是完全跟图片中的尺寸一致。

如果设计图页面是一个banner类型,这样相当于是页面横屏,且高度很低,建议重置mixin中的html根元素字体设置,由vh改为vw,形如:

代码语言:javascript
复制
html{
  width:100vw;
  height:100vh;
  @media screen and (orientation: landscape) {
    font-size: (@baseSize/(@baseDesign / 2)) * 100vw;
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档