移动端rem使用及高清适配

一、相关概念

rem(font size of the root element)是指相对于根元素(html)的字体大小的单位。简单的说它就是一个相对单位。em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。

设备物理像素:通俗的讲设备屏幕有多少个可以闪烁的点 是一个具体的概念 比如iphone6横向就有750个可以改变颜色的点 类似与电视机 如果家里有10年前买的大头电视,你趴在屏幕前仔细看能看到一个个RGB的点 这就是设备的物理像素。

设备独立像素:设备独立像素是一个虚拟的概念,如程序中的css 比如我们将一个div宽度设置为10像素 那么在pc上系统会将这个div显示在屏幕的10个点上

dpr : 设备物理像素 / 设备独立像素

  • iphone3G 设备物理像素320个点 设备独立像素320px 那么dpr就是1
  • iphone6 设备物理像素750个点 设备独立像素375px 那么dpr就是2
  • iphoneX 设备物理像素1125个点 设备独立像素375px 那么dpr就是3

二、需要解决的问题

1、字体大小需要在根据不同手机屏幕大小适配

2、图片需要根据不同手机的dpr进行适配(解决屏幕高清图片问题)

3、解决移动端0.5px细线问题。

三、解决方法

1、根据不同手机的屏幕大小和dpr设置html根字体大小,使用rem布局。

2、设置页面窗口的缩放比例。

function flex (baseFontSize, normal, fontscale) {
  const win = window
  const REM_BASE_SIZE = 100
  const _baseFontSize = baseFontSize || REM_BASE_SIZE
  // const _fontscale = fontscale || 1
  const doc = win.document
  const ua = navigator.userAgent
  const matches = ua.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i)
  const UCversion = ua.match(/U3\/((\d+|\.){5,})/i)
  const isUCHd = UCversion && parseInt(UCversion[1].split('.').join(''), 10) >= 80
  const isIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi)
  let dpr = win.devicePixelRatio || 1
  if (!isIos && !(matches && matches[1] > 534) && !isUCHd) {
    // 如果非iOS, 非Android4.3以上, 非UC内核, 就不执行高清, dpr设为1;
    dpr = 1
  }
  const scale = normal ? 1 : 1 / dpr
  localStorage.setItem('initial-scale', scale)
  let metaEl = doc.querySelector('meta[name="viewport"]')
  if (!metaEl) {
    metaEl = doc.createElement('meta')
    metaEl.setAttribute('name', 'viewport')
    doc.head.appendChild(metaEl)
  }
  const currentScreenW = window.screen.availWidth || 375
  console.log(currentScreenW)
  metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`)
  doc.documentElement.style.fontSize = normal ? '50px' : `${_baseFontSize / 2 * dpr * currentScreenW / 375}px`
  let _fontscale_ = 1
  if (currentScreenW < 375) {
    _fontscale_ = currentScreenW / 375
    doc.documentElement.style.fontSize = normal ? '50px' : `${_baseFontSize / 2 * dpr * currentScreenW / 375}px`
  }
  localStorage.setItem('font-scale', _fontscale_)
}
export default flex(75)

四、注意事项 

1、入口的html文件不需要再设置mata|viewport标签,上述代码会根据手机的dpr动态生成。

2、第三方插件默认按dpr=1的情况书写样式,会导致页面布局整体缩小。解决方法如下:

  • 使用px2rem-loader将插件的px转化为rem,前提是px2rem-loader设置的remUnit应当为rem基准的一半。比如我们设置iphone6(dpr=2)的根字体为为100px,px2rem-loader设置的remUnit就是50。我们目前设置的iphone6(dpr=2)的根字体为为75px(参照UI设计图为375),px2rem-loader设置的remUnit就是37.5。
  • 当第三方插件使用的是行内样式时,px2rem-loader也不能把px转化为rem。(这种情况不多,后续继续研究,如遇到,少量样式可手动修改处理)

3、img的width和height需要写在内联样式里,如需要写行内样式,需要乘以dpr。

4、echart的整体宽高可以设置成rem,与文案字体(如标题,坐标轴文字等)大小和根据html根字体进行百分比转化。

  • 如设置的iphone6(dpr=2)根字体为为75px,UI设计稿(375px)标题字体为18px,则可以设置echart的标题字体参数为18*2/75=48%。

五、以前采坑

以前使用的rem适配方法如下:主要使用了lib-flexible和px2rem-loader。

1、下载并引入lib-flexible,根据不同手机的dpr动态生成mata|viewport标签

2、使用px2rem-loader将px转化为rem,包括自己写的样式及第三方插件样式(行内样式除外)

3、对于蓝湖375px的设计稿,设置px2rem-loader的转化标准的37.5,可解决第三方插件的样式问题。

但存在两个误区:

1、lib-flexible能解决不同型号苹果手机的dpr问题,但安卓没做处理,默认安卓机drp=1。

2、在处理一个旧项目问题(未使用rem)的一个解决方案是在入口html文件手动创建了mata|viewport标签,写死了缩放比例,也就是dpr=1,导致lib-flexible没生效,当时还以为这方法完美地解决了第三方插件的样式问题。但是图片的高清问题得不到解决。

六、后续开发建议

1、引入flexible.js,设置基准为1rem=100px(iphone6),设置UI设计稿为rem/px为50,自己写的样式统一使用rem,第三方组件使用px2rem-loader将px转化为rem,remUnit设置值为50。1px的细线可以写成0.02rem。

2、引入flexible.js,设置基准为1rem=75px(iphone6),设置UI设计稿为rem/px为37.5,自己写的样式统一使用px,第三方组件使用px2rem-loader将px转化为rem,remUnit设置值为37.5。1px细线使用伪类元素生成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值