当前位置: 首页 > news >正文

移动端适配问题解决方案

前言

随着时间的发展,现在基本上人手一部手机的低头族。做为前端开发的程序猿,在开发移动端web应用的时候,对面一堆各色尺寸不一样的屏幕,就有点淡淡的忧伤。

已上是2018年二月份最新的友盟数据,可在 这里查看详情

很明显我们所要实现的就是在上述如此之多的屏幕,都能实现UI大大出的视觉图上的效果。而要实现这样的效果主要有两个难点

  1. 各屏幕适配
  2. Retina屏下的细节处理(主要是1px的问题)

各屏幕适配

各屏幕的适配,有两种方案,flexible + remvw。这三个单词是什么意思,看着很眼熟,但是这两个方案居然是什么呢,请允许我细细道来。

flexible + rem

显而易见,该方案是由rem 以及 flexible组成的。rem (font size of the root element)相对于根元素(即html元素)font-size计算值的倍数,flexible 即 flexible.js, 手淘团队提供的一个为该方案屏幕适配而写的一个库,主要实现的功能就是,根据屏幕的宽度给 html 元素设置一个合适的 font-size 值。

怎么样看的不是很懂是吧。让我来用一个页面场景再复述一遍。

正常情况下,我们的UI大大会以iphone6的尺寸为标准,做一套视觉效果图,并在上面进行标注,给到我们的标注图,如下所示

拿到这个图 我们该如何下手呢

  1. 先设置 html 元素的 font-size, 这个值我们暂时设置为 font-size: 37.5px,即1rem = 37.5px;
  2. 以iphone6为例子,其屏幕宽度为 750px, 整个屏幕的宽度即 20rem = 37.5 * 20px = 750px;
  3. 此时手机号的输入框为 490px = 13.06777777rem
  4. 依次将页面上的px转换为rem,这样我们就得到了全是rem为尺寸单位的页面

到这里为止是不是就结束了呢 ? 很遗憾的告诉你并不是。为什么 html 元素的 font-size 要设置为 37.5px呢?现在这个界面在iphone6上能完美显示了,在iphone5s,iphone6p能完美显示吗?(iphone6, iphone6s, iphone7. iphone8屏幕没有发生变化,本文直接用iphone6代替了。) 上面的两个问题 我们还有没解决,这个时候就轮到flexible登场了。只需要像如下引入就可实现用js来自动根据屏幕宽度设置 html元素的font-size的值。

<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
复制代码

引申一下

在上述过程中,你会发现,UI给到我们的一般是px标注的图,我们将其转化为rem,这个过程其实会花费很大的计算时间。做为一个合格的程序员,我们应该把这种机械性无脑的操作交给计算机来实现。我使用的是PostCss的插件 postcss-px2rem,这个插件能让我们在写代码时候直接写px,在构建的时候自动将我们所写的px转换为rem,大大提升了我们的开发效率。

vw

这个vw的方案,相当而言还比较新。vw 即(viewport width)可视窗口的宽度。之所以把这个方案放在后面来说,是因为viewport在去年(2017年)的时候存在不少的兼容性问题,各个浏览器的支持并不是很好。但是来到了2018年这个时间点,viewport单位意见得到了众多浏览器的支持(80.45%)。

可以在 这里查看。

接下来就让我们来正式了解下这个方案吧。 vw既然是一个尺寸单位,那它的宽度等于多少呢?等于1%整个屏幕的宽度。举个例子,再次以iphone6手机为例,100vw = 750px => 1vw = 7.5px

再一次那上次的界面做示范

  1. 根据定义,我们了解了在iphone6手机上 1vw = 7.5px
  2. 此时手机号的输入框为 490px = 65.333333vw
  3. 依次将页面上的px转换为vw,这样我们就得到了全是vw为尺寸单位的页面

到这里为止是不是就结束了呢? 是的就是这么简单。

引申一下

跟之前一样的痛点,我们仍然需要花费大量不必要的计算时间去把标注图中的px转换为vw,有没有类似于postcss-px2rem的工具呢?很荣幸能再次站在巨人的肩膀上,已经有大神写了了类似的PostCss插件 postcss-px-to-viewport

1px问题

移动端的屏幕不仅仅分辨率有差异,其实还有Retina屏的问题。正常情况下,我们代码里的1px在屏幕上就应该显示一个像素点,但是在Retina屏下则不仅仅是一个像素点。再次拿iphone6为例,其dpr(device pixel ratio)设备像素比为2,css中一个1x1的点,其实在iphone6上是2x2的点,并且1px的边框在devicePixelRatio = 2的Retina屏下会显示成2px,在iPhone6 Plus下甚至会显示成3px。

这样的话,我们就会发现在有些手机上1px明显跟另外的一些手机的1px粗细不一样。 其实大多数的小公司不会扣这样的一个细节,比如说我们公司不会。(^__^) 嘻嘻……

但是作为一个有追求的前端工程师,我们应该尽量的把事情做的完美一点,(ps.像大公司看齐,在大公司这个细节问题其实是不容忽视的,为了自己以后的发展前途,我们有必要把这个细节完善掉的。)

这个问题的解决方案有很多,个人觉得最简单方面的还是大漠大大的一种解决方案。使用postcss-write-svg插件,

@svg 1px-border {
  height: 2px;
  @rect {
    fill: var(--color, black);
    width: 100%; height: 50%;
    }
  }
.example {
  border: 1px solid transparent;
  border-image: svg(1px-border param(--color #00b1ff)) 2 2 stretch;
}
复制代码

编译出来就是

.example {
  border: 1px solid transparent;
  border-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E") 2 2 stretch;
}
复制代码

其他

小程序中的屏幕适配

最近在写小程序,在小程序里,使用的是小程序的那套,跟平时用的vue全家桶以及react全家桶不一样,并没有配置webpack,在这种情况下我们使用postcss其实很困难(反正我是搞不出来/(ㄒoㄒ)/~~)

那该怎么办呢,小程序提供了一个自己的单位, rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6p1rpx = 0.552px1px = 1.81rpx

我们直接用拿到iphone6的标注图,直接写rpx就好。棒?

总结

如果仔细看一下的话,会发现之前的rem的方案其实就是模拟了vw的实现方案,两者有非常多的相似之处。在lib-flexible的github上有着这样的一句话。

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。vw的兼容方案可以参阅《如何在Vue项目中使用vw实现移动端适配》一文。

我们可以得到一个很明确的信息,lib-flexible这个方案已经被放弃使用了,我们可以去拥抱vw的那套实现方案。

本文参考了大漠大大在 www.w3cplus.com 里的多篇文章

  1. 使用Flexible实现手淘H5页面的终端适配
  2. 再聊移动端页面的适配
  3. 走向视网膜(Retina)的Web时代
  4. 再谈Retina下1px的解决方案
  5. 小程序-wxss

转载于:https://juejin.im/post/5add7a44f265da0b886d05f8

相关文章:

  • 每天一个linux命令(20):find命令之exec
  • 多张图片合成一张图片、兼容问题总结
  • git 配置多个账户
  • CentOS下安装php扩展exif
  • Alembic基本使用
  • 机器学习中特征的处理及选择
  • Prometheus Querying Function rate() vs irate()
  • 多线程基础篇(3)——初试锁
  • java获取文件列表,并按照目录的深度及文件名的拼音的升序排列
  • 爬虫大作业
  • 散列表解决冲突的办法
  • 访谈:摩尔定律后时代,看13位行业专家如何看量子计算机的未来?
  • 青云QingCloud黄允松:关于云计算未来的三个预测
  • slim.flatten——将输入扁平化但保留batch_size,假设第一维是batch
  • 深入浅出MyBatis:MyBatis插件及开发过程
  • 《Java编程思想》读书笔记-对象导论
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • Android 架构优化~MVP 架构改造
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • fetch 从初识到应用
  • httpie使用详解
  • Just for fun——迅速写完快速排序
  • vue的全局变量和全局拦截请求器
  • windows下如何用phpstorm同步测试服务器
  • 包装类对象
  • 工作手记之html2canvas使用概述
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 七牛云假注销小指南
  • 使用SAX解析XML
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 新手搭建网站的主要流程
  • 【干货分享】dos命令大全
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • (1)(1.11) SiK Radio v2(一)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (Git) gitignore基础使用
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • .net core 依赖注入的基本用发
  • .Net CoreRabbitMQ消息存储可靠机制
  • .net打印*三角形
  • /etc/motd and /etc/issue
  • /usr/bin/env: node: No such file or directory
  • @angular/cli项目构建--Dynamic.Form
  • @Async注解的坑,小心
  • @RequestParam详解
  • @Transaction注解失效的几种场景(附有示例代码)
  • [].slice.call()将类数组转化为真正的数组
  • [20170728]oracle保留字.txt
  • [acm算法学习] 后缀数组SA
  • [BUAA软工]第一次博客作业---阅读《构建之法》