阅读 3648
详解移动端1px 问题

详解移动端1px 问题

本篇文章首发于我的个人博客:cherryblog.site/#/ ,欢迎大家到我的博客查看更多文章~

为什么会有 1px 问题

移动端 1px 的问题简单的说,就是我们在 pc 的浏览器上设置的 1px 的边框,在移动端的浏览器上看上去会“更粗” 一些。

为什么会有这个问题呢?需要我们先了解几个概念

物理像素

像素,为影像显示的基本单位,译自英文pixel”,pix是英语单词picture的常用简写,加上英语单词“元素”element,就得到pixel,故“像素”表示“画像元素”之意,有时亦被称为pelpicture element)。每个这样的消息元素不是一个或者一个方块,而是一个抽象的取样。仔细处理的话,一幅影像中的像素可以在任何尺度上看起来都不像分离的点或者方块;但是在很多情况下,它们采用点或者方块显示。每个像素可有各自的颜色值,可采三原色显示,因而又分成绿三种子像素RGB色域),或者品红CMYK色域,印刷行业以及打印机中常见)。照片是一个个取样点的集合,在影像没有经过不正确的/有损的压缩或相机镜头合适的前提下,单位面积内的像素越多代表分辨率越高,所显示的影像就会接近于真实物体。

-- 维基百科

我们可以简单理解为:物理像素就是物理设备(显示屏)内部一个个的 led 灯。

物理像素是一个硬件参数,表示一块显示屏的显示面板中有多少个最小显示单元。物理像素是固定不变,不可调节的。

比如 iPhone6 的百度百科的介绍里面,主屏分辨率是 1334 x 750像素,那么就是说明 iPhone6 的显示屏有 1334 x 750 个 led 灯。

image.png

渲染像素/渲染分辨率

我们能在显示器上看到影像,是我们设备的硬件系统中的输出设备输出的数字图像通过显示设备显示出来,这中间我们的系统内部的显示器的“缩放引擎”会对物理像素的分配进行再一次的调整。(就是我们常见的修改显示器设置中的分辨率)

在 PC 中,一般渲染分辨率和物理分辨率是一致的,也就是在渲染的时候,每一个的数字图像对应显示器上一个 led 灯。但是可以通过设置来改变渲染分辨率,可以把渲染分辨率调的更低一点,但是展示的效果就会更模糊、不清晰。(同样的图像,比如在高分辨率的设备上在1000个“点”展示,低分辨率只在500个“点”上展示)

image.png

在手机上,物理分辨率一般是比渲染分辨率要大的。

ppi

PPI是Pixels Per Inch缩写,pixels per inch所表示的是每英寸对角线上所拥有的像素(pixel)数目。手机屏幕的PPI当达到一定数值时,人眼就分辨不出颗粒感了。

image.png

根据苹果公司的计算,当手机的 ppi 超过 300 的时候,人的肉眼就无法分辨出单个像素的显示屏,这样的屏幕苹果称之为 Retina屏(视网膜屏)。 iPhone6/iPhone6s/iPhone7 ppi 是 326. iPhone6 Plus 的 ppi 是 401。

image.png

ppi数值越高,代表显示屏能够以越高的密度显示图像,画面的细节就会越丰富。

逻辑像素/DIP

设备独立像素(又称设备无关像素 Device Independent Pixels 、密度独立性 Density Independent或设备独立像素,简称DIP或DP)是一种物理测量单位,基于计算机控制的坐标系统和抽象像素(虚拟像素),由底层系统的程序使用,转换为物理像素的应用。

典型的用途是允许移动设备软件将信息显示和用户交互扩展到不同的屏幕尺寸。允许应用程序以抽象像素为单位进行测量,而底层图形系统将应用程序的抽象像素测量值转换为适合于特定设备的物理像素。

--百度百科

在高 ppi 的显示屏下,高渲染像素会导致页面变小。

比如,iPhone 3GS 和 iPhone 4/4s 的尺寸都是 3.5 寸,但 iPhone 3GS 的分辨率是 320x480,iPhone 4/4s 的分辨率是 640x960,也就是说同样长度的两个手机,iPhone 3GS 上有 320 个物理像素,iPhone 4/4s 上有 640 个物理像素。

如果按照物理像素进行展示,那么实际的展示大小,640物理像素的手机上展示的图像是 320物理像素手机的一半。

为了调和这种差异,系统做的一个纯软件的解决方案。使得图像在不同 ppi 的显示屏上展示相同尺寸的图像。是一个虚拟的像素单位。独立于设备的用于逻辑上衡量长度的单位,由底层系统的程序使用,会由相关系统转换为物理像素。

我们设定 iPhone 3GS 和 iPhone 4/4s 都是 320 个虚拟像素,只是在 iPhone 3GS 上,最终 1 个虚拟像素换算成 1 个物理像素,在 iphone 4s 中,1 个虚拟像素最终换算成 2 个物理像素。

dpr

dpr(devicePixelRatio):设备上物理像素 (physical pixels) 和设备无关像素 (device-independent pixels (dips)) 的比例。公式表示就是:window.devicePixelRatio = physical pixels / dips

在 iPhone6 中,物理像素是 1334 x 750,设备无关像素是 667 x 375,那么 iPhone6 的 dpr 就是2。代表着:2个物理像素对应一个逻辑像素(水平方向 or 垂直方向)。在平面内也就是 4个物理像素对应1个逻辑像素。

CSS像素

我们现在都已经习惯了 CSS中设置长度的单位是 px,经常忽略 px 的含义是什么

像素:是指在由一个数字序列表示的图像中的一个最小单位,称为像素

--百度百科

CSS 像素是逻辑像素的一个子集。是一个相对长度单位。CSS 会在不同的设备之间调节,在不同 ppi 的设备上使得阅读体验一致。

image.png

图像大小

我们通常使用的 png、jpg 图片都是位图,位图是由像素(pixel)组成。像素是位图最小的信息单元。位图按照从左向右,从上到下的顺序来记录图像中每一个像素点的位置和颜色值等信息。单位长度内像素越多,分辨率越高,图像的效果越好。

比如一个图片的大小是 1334 x 750,那么就代表着这个图片有 1334 x 750 个像素点,这个和刚刚的 iPhone6 的分辨率是一样的,那么就代表着这张图片在 iPhone6 上展示一位图像素对应的就是一个设备像素,这就是会是一个完全保真的显示。

但是这个图片在 iPhone6s 或者 iPhone7 上就不是完全保真的展示。所以需要更高分辨率的图片。这也就是为什么设计会给我们 @2x @3x 倍图的原因。

所以,如果设计师给我们的设计稿的宽度是 750px 的宽度,那么对应的 1px 的边框在 375 的渲染像素上就是 0.5px。

如何解决 1px 问题

使用 0.5px

缺点:兼容性

border: 0.5px solid red; 
复制代码

我们可以直接使用 0.5px ,但是并不是所有浏览器都能识别0.5px,只在 Firefox 和 Safari 8+ 支持,安卓不支持。有的系统里0.5px会被当作0px来处理。

border-image

还可以使用 border-image 设置一个透明到边框色的线性渐变

.pink-div{
  width: 100px;
  height: 100px;
  margin-top: 20px;
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(to bottom, transparent 50%, red 50%) 0 0 100%/1px 0;
}
复制代码

image.png

我们将其中的粉色的小方块放大就可以看出, 粉色方块的底部 border 被分成了两部分,上半部是透明的,下半部是红色的。

image.png

box-shadow 模拟边框

.box-shadow-1px{
    box-shadow: 0px 0.5px 0px 0px #ee2c2c;
}
复制代码

缺点:边框有阴影,颜色浅,同样也有兼容性问题,Safari 不支持 1px 以下的 box-shadow。

伪元素 + transform

用媒体查询根据设备像素比用“伪元素+transform”对边框进行缩放。

@media (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2){
  .border-bt-1px{
    position: relative;
    :before{
      content: '';
      position: absolute;
      left:0;           
      bottom: 0;
      width: 100%;
      height: 1px;
      background: #ee2c2c;
      transform: scaleY(0.5);
    }
  }
}
复制代码
文章分类
前端
文章标签