为什么会出现移动端1像素边框问题

viewport的设置和屏幕物理分辨率是按比例而不是相同的,移动端window对象有个devicePixelRatio属性,它表示设备物理像素和CSS像素的比例,在retina屏的iphone手机上,这个值为2或3,CSS里写的1px长度映射到物理像素上就有2px或3px那么长。

用户缩放的影响是?

屏幕显示上的变化,缩放一倍,css像素(逻辑像素)所代表的物理像素也就缩放了一倍,即设备物理像素和设备独立像素的比例增大一倍,即dpr发生变化

专有名词及概念

viewport视口

设备屏幕上能用来显示我们网页内容的那一块区域,具体点就是浏览器或app中的webview用来显示网页的那部分区域,但viewport又不局限于浏览器可视区域的大小,可能大也可能小,体验在用户是否缩放了屏幕

meta标签中的 user-scalable=no 作用为禁止用户缩放

物理像素

物理像素,又称设备像素,在同一个设备上,他的物理像素是固定的,设备厂商出场是就设置好的,即,一个设备的分辨率是固定的

逻辑像素

逻辑像素,又称css像素,viewport中的一个小方格。在使用css代码的时候,用的就是css像素

设备独立像素dip

device independent pixels,设备独立像素,与屏幕密度有关,dip可以用来辅助区分视网膜设备和非视网膜设备

设备像素比dpr

devivePixelRatio指的是window.devicePixelRatio
window.devicePixelRatio是设备上物理像素和设备独立像素(dip)的比例
公式为:window.devicePixelRatio = 物理像素 / dips

像素比

物理像素和逻辑像素的比例,当比例为1:1时,便是1个物理像素显示一个css像素,当比例为2:1时,表示使用4个物理像素显示一个逻辑像素

解决方案

使用媒体查询,定义不同最先像素比下的类border-1px
  1. @media (-webkit-min-device-pixel-ratio: 1.5),(min-device-aspect-ratio: 1.5) {
  2. .border-1px{
  3. &::after{
  4. transform:scaleY(0.7); //1.5 * 0.7接近1
  5. }
  6. }
  7. }
  8. @media (-webkit-min-device-pixel-ratio: 2),(min-device-aspect-ratio: 2) {
  9. .border-1px{
  10. &::after{
  11. transform:scaleY(0.5); //2 * 0.5 = 1
  12. }
  13. }
  14. }
  15. @media (-webkit-min-device-pixel-ratio: 2.5),(min-device-aspect-ratio: 2.5) {
  16. .border-1px{
  17. &::after{
  18. transform:scaleY(0.4); //2.5 * 0.4 = 1
  19. }
  20. }
  21. }
  22. @media (-webkit-min-device-pixel-ratio: 3),(min-device-aspect-ratio: 3) {
  23. .border-1px{
  24. &::after{
  25. transform:scaleY(0.333); //3 * 0.333 接近 1
  26. }
  27. }
  28. }
  29. @media (-webkit-min-device-pixel-ratio: 3.5),(min-device-aspect-ratio: 3.5) {
  30. .border-1px{
  31. &::after{
  32. transform:scaleY(0.2857); //3.5 * 0.2857 接近 1
  33. }
  34. }
  35. }

定义mixin border-bottom
  1. @mixin border-bottom($height,$color) {
  2. position:relative;
  3. &::after{
  4. position: absolute;
  5. display: block;
  6. left: 0;
  7. bottom: 0;
  8. width: 100%;
  9. border-top: $height solid $color;
  10. content: '';
  11. }
  12. }
  13. @mixin border-top($height,$color) {
  14. position:relative;
  15. &::after{
  16. position: absolute;
  17. display: block;
  18. left: 0;
  19. top: 0;
  20. width: 100%;
  21. border-top: $height solid $color;
  22. content: '';
  23. }
  24. }

使用
<div id="navbar"></div>

如果想给#navbar添加一个1像素的下边框,先给#navbar添加一个类border-1px如下:

<div id="navbar" class="border-1px"></div>

然后给#navbar设置样式:

#navbar{
    @include border-bottom(1px, #ccc);
}

参考文档

https://www.jianshu.com/p/5ff121936666
http://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/
https://www.jianshu.com/p/af6dad66e49a
https://www.jianshu.com/p/fa670b737a29