Yujie

移动端 1px 边框的问题

1px问题产生的原因

从移动端的角度说个具体的场景,以 iphone6 为例。

iphone6 的屏幕宽度为 375px,设计师做的视觉稿一般是 750px,也就是 2x,这个时候设计师在视觉稿上画了1px 的边框,于是你就写了 “border-width:1px”,so…1px边框问题产生了

对设计师来说它的 1px 是相对于 750px 的(物理像素),对你来说你的1px是相对于375px的(css像素)“实际上你应该是border-width:0.5px”。

具体方案

知道了问题产生的原因,那么解决方案解决方案就好弄了。为了避免大家少走弯路,这里简单带一下网上提到的几种方案:

1、用小数写边框

用媒体查询,加小数的写法

<span class="border-1px">1像素边框问题</span>
.border-1px { border: 1px solid #999 }

@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-1px { border: 0.5px solid #999 }
}

@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border-1px { border: 0.333333px solid #999 }
}

优点:方便

缺点:安卓与低版本 IOS 不适用

2、伪元素 transform

利用伪类标签,更具父级定位,大小更具媒体查询缩放实现效果。

<span class="border-1px">1像素边框问题</span>
.border-1px {
  position: relative;
}

.border-1px::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 200%;
  border: 1px solid red;
  color: red;
  height: 200%;
  -webkit-transform-origin: left top;
  transform-origin: left top;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  pointer-events: none; 
  box-sizing: border-box;
}

@media screen and (min-device-pixel-ratio: 3),
  (-webkit-min-device-pixel-ratio: 3) {
  width: 300%;
  height: 300%;
  -webkit-transform: scale(0.33);
  transform: scale(0.33);
}

优点:不止是圆角, 其他的边框也可以这样做出来

缺点:代码量也很大,占据了伪元素,,容易引起冲突

3、box-shadow

利用阴影来模拟边框

<span class="border-1px">1像素边框问题</span>
.border-1px{
  box-shadow: 0px 0px 1px 0px red inset;
}

4、Border-image

弄出 1px 像素边框的实质是弄出 0.5px 这样的边框,所以我们可以利用类似于这样的图片,使得 “border-image-slice” 为 2,那么实际上边框有一半是透明的,即可得到我们想要的“ 1px 边框”。

<div class="test">
    1像素边框
</div>
.test{
    border: 1px solid transparent;
    border-image: url('./border-1px.png') 2 repeat;
}

Border-image 兼容性:

缺点:修改颜色麻烦,需要替换图片;圆角需要特殊处理,并且边缘会模糊

参考文章

移动端1px细线解决方案总结

再谈Retina下1px的解决方案

7 种方法解决移动端 Retina 屏幕 1px 边框问题