# 1px问题
在移动端上,有时候明明设置border: 1px
,但对于视觉同事会认为线条比较粗 (如下图)。
# 原因
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- 定义了页面的
viewport
宽度 为 设备宽度,初始缩放值 和 最大缩放值 都为 1,同时禁用了用户缩放。
- 定义了页面的
- dpr导致。
- 对于Retina屏,会使用 多个设备像素 去渲染
.border {
/* 在 DPR 为 2 时,会用 2 个设备像素 去渲染这个border height */
border: 1px solid white;
}
1
2
3
4
2
3
4
更多:像素dpr
综上,是由于设定了缩放值 <meta>
,以及 dpr
导致。
# 解决
有 3 个解决方式:媒体查询 + 小数、flexible、伪元素 + transform。
# 媒体查询、小数
不建议:低版本的安卓、IOS(8以下)不兼容小数。
.border {
border: 1px solid red;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border {
/* 部分机型不兼容小数 */
border: 0.5px solid red;
}
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border {
/* 部分机型不兼容小数 */
border: 0.33333px solid red;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# flexible.js
- 动态计算出
viewport
中scale
缩放。
scale = 1 / devicePixelRatio
metaElem = document.createElement('meta')
metaElem.setAttribute('name', 'viewport')
metaElem.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no')
1
2
3
4
5
2
3
4
5
# 伪元素 + transform
单独缩放 伪元素 不会影响 元素本身 的缩放。
先判断是否为 “Retina屏” (若是,加上一个class)
把
原先元素border去掉
,利用 伪元素::after
重做border,并缩放transform: scale(0.5)
// 利用 js 判断是否为 dpr为 2 的Retina 屏
if (window.devicePixelRatio && devicePixelRatio === 2) {
document.querySelector('div').className = 'scale-1px'
}
1
2
3
4
2
3
4
/*
* 父元素
* 1. 相对定位
* 2. 去掉border
*/
.scale-1px {
position: relative; /* 相对定位 */
border: none; /* 去掉border */
}
/*
* 伪元素
* 1. 绝对定位,定位父容器左上角
* 2. 定义 1px 的 border
* 3. 将宽高放大 200%
* 4. 缩小 0.5
* 5. transform-origin: left top
*/
.scale-1px:after {
content: ' ';
position: absolute;
top: 0;
left: 0;
border: 1px solid red;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top; /* 更改元素的转换原点为左上角 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 对于圆边框的 1px 解决方案
- 方法一:采用 伪类 +
box-sizing: border-box
- 方法二:根据设备DPR计算出
viewport
中的scale
缩放