1px 边框问题(Retina 屏)的多种解决方案

在 Retina 屏幕(高 DPI 设备)上,CSS 中的 1px 边框往往会显示得比实际更粗。这是因为 Retina 屏幕的物理像素密度更高,而 CSS 像素是逻辑像素。例如,在设备像素比为 2 的屏幕上,1 个 CSS 像素实际上由 4 个物理像素(2×2)组成,导致 1px 边框看起来比预期的更粗。

解决方案

1. 使用 0.5px 边框

css 复制代码
.border {
  border: 0.5px solid #000;
}

优点:简单直接
缺点:兼容性较差,部分浏览器不支持小数像素

2. 使用 transform 缩放

css 复制代码
.border {
  position: relative;
}

.border::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  border: 1px solid #000;
  transform: scale(0.5);
  transform-origin: 0 0;
}

优点:兼容性好
缺点:需要额外元素或伪元素

3. 使用 viewport 缩放

html 复制代码
<meta name="viewport" content="width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

优点:全局解决方案
缺点:影响整个页面的布局和字体大小

4. 使用 border-image

css 复制代码
.border {
  border-width: 1px;
  border-image: url(border.png) 2 stretch;
}

优点:可以实现复杂边框效果
缺点:需要准备图片,不够灵活

5. 使用 box-shadow

css 复制代码
.border {
  box-shadow: 0 0 0 0.5px #000;
}

优点:简单易用
缺点:不支持圆角边框

6. 使用 SVG 方案

css 复制代码
.border {
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'><rect width='100%' height='100%' fill='none' stroke='black' stroke-width='1'/></svg>");
}

优点:矢量图形,清晰度高
缺点:代码稍复杂

最佳实践建议

  1. 对于简单的边框需求,推荐使用 transform 缩放方案,兼容性好且效果稳定
  2. 如果项目使用了预处理工具,可以将方案封装为 mixin 或函数方便复用
  3. 在移动端项目中,可以考虑结合媒体查询针对不同设备像素比应用不同方案
scss 复制代码
@mixin retina-border($color: #000, $radius: 0) {
  position: relative;
  
  &::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;
    height: 200%;
    border: 1px solid $color;
    border-radius: $radius * 2;
    transform: scale(0.5);
    transform-origin: 0 0;
    pointer-events: none;
  }
}

@media (-webkit-min-device-pixel-ratio: 2) {
  .element {
    @include retina-border(#ccc, 4px);
  }
}

通过以上多种方案,开发者可以根据项目需求和兼容性要求选择最适合的方法来解决 Retina 屏幕下的 1px 边框问题。