CSS样式1px在Retina屏幕显示器上显示发虚的问题

Web前端开发 / 20 次阅读

Retina屏幕拥有比普通屏幕高得多的像素密度,比如一台13英寸的笔记本电脑可能拥有2560x1600的物理分辨率,但默认的系统设置会让它以一个类似1280x800的“逻辑分辨率”来工作,而在Retina屏幕上,1个逻辑像素实际上是由2x2=4个物理像素来共同显示的(DPR=2),这样做的目的是为了显示更细腻的文字和图像,因为一个逻辑点有更多物理像素来渲染,边缘会更平滑。

所以在CSS中写border: 1px solid black;时,定义的是1个逻辑像素的边框,但对于浏览器来说,则需要把这1个逻辑像素的粗细用2个物理像素的高度(或宽度)来呈现。那么如何用2个物理像素渲染1个逻辑像素?因为它无法完美分割,所以浏览器会采用抗锯齿(Anti-aliasing)算法,尝试用灰阶过渡来让这条线“看起来”更细,这个过程就导致了本应是纯色的“1px”边框变得有些模糊、发虚,在某些背景色下会尤其明显。

解决方法一:

在写CSS样式时可以使用transform:scale()来实现真正的“物理1像素”的细边框,通常称为 “1px方案”。这是目前最流行、兼容性最好的方案。它的原理是将元素的高度压缩到物理像素级别。

CSS代码:
.border {
    width:100px;
    height:1px;
    background-color:#f00;
    transform: scaleY(0.5); /* 在Y轴方向上压缩到原来的50%,即1个物理像素 */
    transform-origin: 0 bottom; /* 设置压缩的基准线为底部,让压缩向下发生 */
}

解决方法二:

使用媒体查询(Media Query)和min-resolution,针对高DPI屏幕专门写样式,普通屏幕则用原来的1px。

/*普通屏幕 */
.border {
    width:100px;
    height:1px;
    background-color:#f00;
}

/*针对DPR >= 2的屏幕*/
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
    .border {
        height: 0.5px;
    }
}

推荐方法一。