# 极细边框（1px边框）实现方式

移动端 `web`开发遇到的问题：UI稿上要求设置边框为`1px`，css设置`border: 1px solid #eee;`之后，UI又说边框太粗了。

这是因为`devicePixelRatio`特性导致。css设置的`1px`是**css像素**，而UI稿上指的是**设备像素**，它们之间存在一个比例关系，即，`devicePixelRatio`。iPhone的`devicePixelRatio == 2`，而`border-width: 1px`描述的是css像素，所以，`border`被放大到物理像素`2px`显示，在`iPhone`上就显得较粗。

## 像素基本概念（术语）

**device pixel / physical pixel （设置像素、物理像素、硬件像素）：** **显示屏中最小的物理单元**。 移动设备出厂时，不同设备自带的不同像素，每个像素点根据操作系统的指示设置自己的颜色和亮度。

**density-independent pixel(DIP)（设备无关像素或密度无关像素）：可以认为是计算机坐标系统中得一个点**，这个点代表一个可以由程序使用的虚拟像素，然后由相关系统转换为物理像素。

\*\*CSS pixel （css 像素）：\*\*浏览器使用的抽象单元，用于精确地，一致地在网页上绘制内容。 通常，**CSS 像素被称为与设备无关的像素（DIP）**。

\*\*devicePixelRatio（设备像素比）：\*\*物理像素和逻辑像素的比例关系，通常可以通过`js`的 `window.devicePixelRatio` 来获取。

**devicePixelRatio**可以用来区分视网膜设备还是非视网膜设备。

`devicePixelRatio` 值为 1 的屏幕称之为标准屏（也称，非视网膜屏）；目前，大部分移动设备都是高清屏（也称，视网膜屏），即 `devicePixelRatio` 值大于 1 的屏幕，对于苹果设备来说，我们经常听到 `Retina`屏（视网膜屏），其中 `iPhone6/6s/7` 的 `devicePixelRatio` 值为 2；而 `iPhone6 plus/6s plus/7 plus` 的 `devicePixelRatio` 值为 3。

## 设置0.5px边框

\*\*优点：\*\*实现简单

**缺点：**`retina` 屏的浏览器可能不认识`0.5px`的边框，将会把它解释成`0px`，没有边框。包括 `iOS 7` 和之前版本，`OS X Mavericks` 及以前版本，还有 `Android` 设备。

```js
//判断手机是否支持0.5px
if (window.devicePixelRatio && devicePixelRatio >= 2) {
    var divElem = document.createElement('div')
    divElem.style.border = '.5px solid transparent'
    document.body.appendChild(divElem)
    if (divElem.offsetHeight == 1) {
        document.querySelector('html').classList.add('hairlines');
    }
    document.body.removeChild(divElem);
}


//在html中，加上此样式
.hairlines {
    *:not(table tr td),
    *:not(.noHairlines) {
        border-width: 0.5px!important;
    }
}
```

## box-shadow（阴影）

\*\*优点：\*\*可以设置圆角

\*\*缺点：\*\*颜色不好控制

```css
.border-1px {
	box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
```

## border-image（边框背景图片）

使用的图片是`2px`高，上部的`1px`颜色为透明，下部的`1px`使用视觉规定的`border`的颜色。

**优点：**

\*\*缺点：\*\*修改颜色麻烦，需要替换图片；圆角需要特殊处理，并且边缘会模糊。

```css
.border-image-1px {
    border-width: 1px 0px;
    border-image: url("data:image/png;base64,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") 2 0 stretch;
}
```

## background-image 渐变

\*\*缺点：\*\*不能实现圆角。

```css
.border-1px {
	background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
        linear-gradient(270deg, red, red 50%, transparent 50%),
        linear-gradient(0deg, red, red 50%, transparent 50%),
        linear-gradient(90deg, red, red 50%, transparent 50%);
	background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
    background-repeat: no-repeat;
    background-position: top, right top,  bottom, left top;
    padding: 10px;
}
```

## transform: scale(0.5) （推荐，相当灵活）

```css
/*height：1px，然后根据媒体查询设置transform: scaleY(0.5)*/
.border-1px {
    height:1px;
    background:#000;
    transform: scaleY(0.5);
    transform-origin:0 0;
    overflow: hidden;
}
```

```css
/*伪类::after和::befor,设置border-bottom：1px solid #000,然后在缩放transform: scaleY(0.5),可以实现两根边线的需求*/
.border-1px:after,
.border-1px::after {
    content:'';
    width:100%;
    border-bottom:1px solid #000;
    transform: scaleY(0.5);
}
```

```css
/*伪类::after设置border：1px solid #000; width:200%; height:200%,然后再缩放scale(0.5); 优点可以实现圆角，缺点是按钮添加active比较麻烦。*/
.border-1px:after,
.border-1px::after {
    content: '';
    width: 200%;
    height: 200%;
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #bfbfbf;
    border-radius: 4px;
    transform: scale(0.5,0.5);
    transform-origin: top left;
}
```

## viewport+rem

\*\*优点：\*\*可以自适应已知的各类手机屏幕,且不存在其它方法存在的变颜色困难、圆角阴影失效问题。

\*\*缺点：\*\*样式必须用rem为单位

```js
var viewport = document.querySelector("meta[name=viewport]");  
//下面是根据设备像素设置viewport  
if (window.devicePixelRatio == 1) {  
    viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');  
}  
if (window.devicePixelRatio == 2) {  
    viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');  
}  
if (window.devicePixelRatio == 3) {  
    viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');  
}  
var docEl = document.documentElement;  
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';  
docEl.style.fontSize = fontsize; 
```

## 常见问题

### 细边框显示不全

![](https://my-files-1259410276.cos.ap-chengdu.myqcloud.com/md_images/webdevice-1pxborder.png)

**原因**： 未确定。可能与元素的高度、行高及像素的小点有关

**解决方法**：

1. 上边框被遮住：如果样式中有 `position: absolute； top：50%` ，可以尝试把改成 `top: 51%`。
2. 尽量不要使用`display: inline-block`，改用`display: block`。
3. 将`0.5px`改为`0.7px`。
4. 指定高度、行高（如：`line-height: normal`）。

## **参考链接**

[移动web 1像素边框 瞧瞧大公司是怎么做的](https://segmentfault.com/a/1190000007604842)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lizh.gitbook.io/knowledge/research/01-ji-xi-bian-kuang-1px-bian-kuang-shi-xian-fang-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
