移动端适配以及1px边框解决方案

分享一些自己平时项目用到的移动端适配,本人主要用的是vw适配并没有rem。如果哪里写的有问题欢迎指出。

vw(viewport units)单位,何谓视口,就是根据你浏览器窗口的大小的单位,不受显示器分辨率的影响、不受viewport 设置影响。

这里移动端适配用的是postcss-px-to-viewport

Installation

Add via npm

$ npm install postcss-px-to-viewport --save-dev复制代码

or yarn

$ yarn add postcss-px-to-viewport
复制代码

一般设计图的标准都是以iphone6为基准 iPhone6的宽度为750 iPhone6的宽度为1334

Usage

Default Options:


    "postcss-px-to-viewport": {
      viewportWidth: 375,  //视窗的宽度,对应的是我们设计稿的宽度,一般是750 我们这里是375
      viewportHeight: 667, // 视窗的高度,以iPhone的基准就是1334 我们这里是667
      unitPrecision: 1, // 指定px转换为视窗单位的小数位数(很多时候是无法整除的)我们这里选择一位小数 是因为偶尔在安卓手机小数位数为1位以上的时候、画出来的圆形是椭圆形。
      viewportUnit: 'vw', // 指定需要转换成的视窗单位 vw不解释
      selectorBlackList: [   // 要忽略的选择器并保留为px
        'hairlines'
      ],
      minPixelValue: 1, // 设置要替换的最小像素值  因为需要做1px的边框适配  所以这里必须是1px
      mediaQuery: false // 允许在媒体查询中转换px
    },
复制代码

下面是我写的配合vw的解决方案 Vue项目


import Vue from "vue"; //debug function warn(msg: string, err?: Error): void { if (typeof console !== 'undefined') { console.warn('[vue-flexible] ' + msg) if (err) { console.warn(err.stack) } } } // 判断设备是安卓还是ios

const isServer: boolean = Vue.prototype.$isServer; const UserAgent:string = window.navigator.userAgent; function isAndroid(): boolean { return isServer ? false : /android/.test(UserAgent.toLowerCase()); }

function isIOS(): boolean { return isServer ? false : /ios|iphone|ipad|ipod/.test(UserAgent.toLowerCase()); }

const doc: Document = window.document; const docEl = doc.documentElement; let metaEl: any = doc.querySelector('meta[name="viewport"]'); let dpr: number = 0; let scale: number = 0;

//如果有meta标签根据已有的设置缩放比例 if (metaEl) { warn('将根据已有的meta标签来设置缩放比例'); let match = metaEl.getAttribute('content').match(/initial-scale=([\d.]+)/); if (match) { scale = parseFloat(match[1]); dpr = 1 / scale; } }

//没有的话ios dpr为2的时候 viewport为0.5 dpr为3的时候 viewport为.33 //安卓全部viewport为1 检测浏览器是否支持1px边框 如果支持 html添加类名 hairlines if (!dpr && !scale) { const devicePixelRatio:number = window.devicePixelRatio; docEl.setAttribute('data-dpr', ${devicePixelRatio}复制代码); if (isIOS) { docEl.setAttribute('data-device', 'iphone'); if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) { dpr = 2; } else { dpr = 1; } } else if (isAndroid) {

    docEl.setAttribute('data-device', 'android');
    if (devicePixelRatio >= 2) {
        const fakeBody = doc.createElement('body');
        const testElement = doc.createElement('div');
        testElement.style.border = '.5px solid transparent';
        fakeBody.appendChild(testElement);
        docEl.appendChild(fakeBody);
        if (testElement.offsetHeight === 1) {
            docEl.classList.add('hairlines');
        }
        docEl.removeChild(fakeBody);
    }
    dpr = 1
} else {
    dpr = 1;
}
scale = 1 / dpr;
复制代码

}

if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', width=device-width,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale},user-scalable=no,viewport-fit=cover复制代码);

if (docEl.firstElementChild) {
    docEl.firstElementChild.appendChild(metaEl);
} else {
    const wrap = doc.createElement('div');
    wrap.appendChild(metaEl);
    doc.write(wrap.innerHTML);
}
复制代码
复制代码

} 复制代码

附加安卓1px边框 sass函数


@mixin hairlines($border-width:1px, ) {
    border-width: $border-width;
    $selector: &;
    @at-root {
        .hairlines #{$selector} {
            border-width: $border-width/2;
        }
    }
}
复制代码
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值