---
comments:true
---

# 1px 边框问题

[7 种方法解决移动端 Retina 屏幕 1px 边框问题](https://juejin.im/entry/584e427361ff4b006cd22c7c)

[在 retina 屏中实现 1px border 效果](http://imweb.io/topic/55e3d402771670e207a16bd1)




#### 下文出自[7 种方法解决移动端 Retina 屏幕 1px 边框问题](https://juejin.im/entry/584e427361ff4b006cd22c7c)

### 造成边框变粗的原因

其实这个原因很简单，因为 css 中的 1px 并不等于移动设备的 1px，这些由于不同的手机有不同的像素密度。在 window 对象中有一个 devicePixelRatio 属性，他可以反应 css 中的像素与设备的像素比。

> devicePixelRatio 的官方的定义为：设备物理像素和设备独立像素的比例，也就是 devicePixelRatio = 物理像素 / 独立像素。

### 0.5px 边框

```js
if (window.devicePixelRatio && devicePixelRatio >= 2) {
    var testElem = document.createElement("div");
    testElem.style.border = ".5px solid transparent";
    document.body.appendChild(testElem);
    if (testElem.offsetHeight == 1) {
        document.querySelector("html").classList.add("hairlines");
    }
    document.body.removeChild(testElem);
}
// 脚本应该放在内，如果在里面运行，需要包装 $(document).ready(function() {})
```

```css
div {
    border: 1px solid #bbb;
}
.hairlines div {
    border-width: 0.5px;
}
```

### 使用 border-image 实现

```css
/* 底部边框 */
.border-bottom-1px {
    border-width: 0 0 1px 0;
    -webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
    border-image: url(linenew.png) 0 0 2 0 stretch;
}
/* 上下边框 */
.border-image-1px {
    border-width: 1px 0;
    -webkit-border-image: url(linenew.png) 2 0 stretch;
    border-image: url(linenew.png) 2 0 stretch;
}
/* 使用Media Query做兼容 */
.border-image-1px {
    border-bottom: 1px solid #666;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .border-image-1px {
        border-bottom: none;
        border-width: 0 0 1px 0;
        -webkit-border-image: url(../img/linenew.png) 0 0 2 0 stretch;
        border-image: url(../img/linenew.png) 0 0 2 0 stretch;
    }
}
```

### 使用 background-image 实现

```css
.background-image-1px {
    background: url(../img/line.png) repeat-x left bottom;
    -webkit-background-size: 100% 1px;
    background-size: 100% 1px;
}
```

### 多背景渐变实现

```css
.background-gradient-1px {
    background: linear-gradient(180deg, black, black 50%, transparent 50%) top left /
            100% 1px no-repeat, linear-gradient(
                90deg,
                black,
                black 50%,
                transparent 50%
            ) top right / 1px 100% no-repeat,
        linear-gradient(0, black, black 50%, transparent 50%) bottom right / 100%
            1px no-repeat, linear-gradient(
                -90deg,
                black,
                black 50%,
                transparent 50%
            ) bottom left / 1px 100% no-repeat;
}
/* 或者 */
.background-gradient-1px {
    background: -webkit-gradient(
            linear,
            left top,
            left bottom,
            color-stop(0.5, transparent),
            color-stop(0.5, #c8c7cc),
            to(#c8c7cc)
        ) left bottom repeat-x;
    background-size: 100% 1px;
}
```

### 使用 box-shadow 模拟边框

```css
.box-shadow-1px {
    box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
```

### viewport + rem 实现

同时通过设置对应 viewport 的 rem 基准值，这种方式就可以像以前一样轻松愉快的写 1px 了。在 devicePixelRatio = 2 时，输出 viewport：

````
在devicePixelRatio = 3 时，输出viewport：
```html
````

这种兼容方案相对比较完美，适合新的项目，老的项目修改成本过大。对于这种方案，可以看看《使用 Flexible 实现手淘 H5 页面的终端适配》

### 伪类 + transform 实现

单条 border 样式设置：

```css
.scale-1px {
    position: relative;
    border: none;
}
.scale-1px:after {
    content: "";
    position: absolute;
    bottom: 0;
    background: #000;
    width: 100%;
    height: 1px;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}
```

四条 boder 样式设置:

```css
.scale-1px {
    position: relative;
    margin-bottom: 20px;
    border: none;
}
.scale-1px:after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #000;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
}
```

```js
if (window.devicePixelRatio && devicePixelRatio >= 2) {
    document.querySelector("ul").className = "scale-1px";
}
```