Skip to content

Latest commit

 

History

History
199 lines (137 loc) · 7.26 KB

移动端适配.md

File metadata and controls

199 lines (137 loc) · 7.26 KB

移动端适配

移动端适配

概念

viewport

英文名字叫 viewport,简单理解,严格等于浏览器的窗口。在 pc 端是一直的,移动端有点复杂。因为移动端 viewport 太窄了。为了更好的服务于 css 布局。所以提供了 2 个 viewport,虚拟的 visualviewport 和布局的 layoutviewport。

  • 布局视口:在浏览器窗口 css 的布局区域,布局视口的宽度限制 css 布局的宽。为了能在移动设备上正常显示那些为 pc 端浏览器设计的网站,移动设备上的浏览器都会把自己默认的 viewport 设为 980px 或其他值,一般都比移动端浏览器可视区域大很多,所以就会出现浏览器出现横向滚动条的情况
  • 视觉视口:用户通过屏幕看到的页面区域,通过缩放查看显示内容的区域,在移动端缩放不会改变布局视口的宽度,当缩小的时候,屏幕覆盖的 css 像素变多,视觉视口变大,当放大的时候,屏幕覆盖的 css 像素变少,视觉视口变小。
  • 理想视口:一般来讲,这个视口其实不是真是存在的,它对设备来说是一个最理想布局视口尺寸,在用户不进行手动缩放的情况下,可以将页面理想地展示。那么所谓的理想宽度就是浏览器(屏幕)的宽度了。

layout-vp.jpg

visual-vp.jpg

物理像素

一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。

设备独立像素

计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css 像素),然后由相关系统转换为物理像素。二者有对应关系。 通常指的是“设备的宽高”。eg:iphone6/7/8/x 宽 375,plus 宽 414

设备像素比

物理像素和设备独立像素的对应关系 / dpr。 设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x 方向或者 y 方向(window.devicePixelRatio/媒体查询)

位图像素

理论上:1 个位图像素对应 1 个物理像素才是最清晰的!物理像素过少模糊,物理像素过多缺乏锐或者些许色差!

概念小结

不同屏幕下(普通 vs 高清),css 像素肉眼所见的大小(物理尺寸)是一致的,唯一不同的 1 个 px 对应的物理像素不同。

适配方案

方案一:百分比%

缺点:淘汰了

方案二:REM

有点:简单,兼容性好 缺点:

  • 需要在头部加载一段 js
  • iframe 支持差
  • 手淘的大漠(lib.flexible.js 作者)称其已经完成历史使命,可以拥抱大胆 vw

手淘 lib.flexible.js

新版:直接 dpr 默认均为 1,不再考虑 使用 dpr 进行页面缩放的情况。(根据 dpr 设置 body 字体没搞清楚!)

旧版:两种使用方法。

  1. 设置 meta 标签,不缩放。只处理 iphone 的 dpr(留作后面 css hack 使用)
  2. 设置 meta(不手动设置缩放比)。根据 dpr 来处理页面缩放,自动计算 rem。

方案二:VW

  • vw:是 Viewport's width 的简写,1vw 等于 window.innerWidth 的 1%
  • vh:和 vw 类似,是 Viewport's height 的简写,1vh 等于 window.innerHeihgt 的 1%
  • vmin:vmin 的值是当前 vw 和 vh 中较小的值
  • vmax:vmax 的值是当前 vw 和 vh 中较大的值

兼容性:在移动端 iOS 8 以上以及 Android 4.4 以上获得支持

px2vw 计算,引入 postcss 插件

其他

  • css3 媒体查询
  • VW+REM
    • 解决设置最大最小宽度的问题

字体如何处理

不同精度和大小的屏幕上我们希望看到的字体大小是一样的,字号是相同的。另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是 16px 和 24px,所以我们不希望出现 13px 和 15px 这样的奇葩尺寸。

/*
淘宝基准字体大小是12px
data-dpr是lib-flexible方案在根元素上设置的钩子属性。设置meta后data-dpr均为1(或者不设置)
*/
div {
  width: 1rem;
  height: 0.4rem;
  font-size: 12px;
}
[data-dpr='2'] div {
  font-size: 24px;
}
[data-dpr='3'] div {
  font-size: 36px;
}

微信公总号, 标题 22px,正文 15px(人民日报 18px)

图片解决方案

理论最好:不同 drp 加载不同@2/@3 倍图,缺点是麻烦,需要服务端做改造,机制用户体验和性能要求时需要! 现有方案:直接@2 图,缺点是普通屏幕浪费资源,造成 downsampling。高清屏(dpr2 以上)稍显模糊,不过尚可接受!

1px 解决方案

ios7 和安卓系统,0.5px 会被解析成 0。

.border {
  border: 1px solid black;
}
@media (-webkit-min-device-pixel-ratio: 2) {
  .border {
    border-width: 0.5px;
  }
}

方案一:元素 scale

元素添加.scale 样式,relative 不会改变文档流,伪类设置 border,侵入式较小。TD 不支持!

/* 一条边示例 */
.scale {
  position: relative;
}
.scale:after {
  content: '';
  position: absolute;
  bottom: 0px;
  left: 0px;
  right: 0px;
  border-bottom: 1px solid #ddd;
  -webkit-transform: scaleY(0.5);
  -webkit-transform-origin: 0 0;
}

方案二:页面 scale

<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no"> 页面所有的 border:1px 都将缩小 0.5,当然不论是用什么转换方案,border 固定写 1px。

方案三:border-image 使用图片

方案三(加强版): svg+border-image

使用 postcss 插件 postcss-write-svg

其他方案

  • 用 box-shadow 模拟边框的
  • 多背景渐变实现的

常见问题

百分比和 vw 都是需要计算百分比,那么两个方案的不同之处?

%:width、height 等大部分相对于直接父元素、border-radius、translate、background-size 等相对于自身 vw:只相对于视口宽度

vw 布局元素或者图片如何维持宽高比?

利用 padding-top 实现

.mod_banner {
  position: relative;
  padding-top: percentage(100/750); // 使用padding-top
  height: 0;
  overflow: hidden;
  img {
    width: 100%;
    height: auto;
    position: absolute;
    left: 0;
    top: 0;
  }
}

参考资料