CSS 0.5px 边框
解决高 DPR 设备下细边框显示过粗的问题,常见做法是缩放、伪元素或渐变处理。
#type / concept
#status / growing
#tech / dev / frontend
CSS 0.5px 边框
为什么会出现”边框过粗”问题
设备像素比 (DPR = devicePixelRatio) 决定了 CSS 像素与物理像素的映射关系:
| DPR | 1 CSS px = 物理像素 | 1px border 物理宽度 |
|---|---|---|
| 1 | 1px | 1px |
| 2 | 2px | 2px |
| 3 | 3px | 3px |
在 DPR=2 的 Retina 屏上,border: 1px 实际占 2 个物理像素,视觉上明显偏粗。目标是让边框只占 1 个物理像素,即 CSS 层面的 0.5px。
方案一:transform: scale() 缩放伪元素
最常用的方案,兼容性好。
.border-1px {
position: relative;
}
.border-1px::after {
content: '';
position: absolute;
left: 0;
top: 0;
border: 1px solid #000;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
box-sizing: border-box;
pointer-events: none;
}
原理:伪元素放大 2 倍后再缩小 0.5 倍,1px 边框在 DPR=2 设备上正好占 1 个物理像素。
方案二:box-shadow 模拟
.border-1px {
box-shadow: 0 0 0 0.5px #000;
}
简洁,但视觉效果与实线有差异(阴影有模糊),不适合需要精确边框样式的场景。
方案三:border-image 渐变
.border-1px {
border: none;
border-image: linear-gradient(to right, #000 50%, transparent 50%) 1;
border-width: 0 0 1px 0;
}
可实现单边或多边的 0.5px 效果,但 border-image 与 border-radius 不兼容。
方案四:background-image 渐变
.border-1px {
background-image: linear-gradient(to bottom, #000 50%, transparent 50%);
background-size: 100% 1px;
background-repeat: no-repeat;
background-position: bottom;
}
适合只需单边细线的场景,灵活性高。
方案选择
| 场景 | 推荐方案 |
|---|---|
| 四边都需要 | transform scale |
| 只需单边 | background-image 渐变 |
| 需要圆角 | transform scale(避免 border-image) |
| 追求简洁、可接受模糊 | box-shadow |
浏览器兼容性
0.5px直接设置:iOS 8+ / Safari 支持,Android 部分浏览器不支持transform: scale():全平台兼容border-image:IE11+ 支持- 实际项目中推荐
transform: scale()方案,覆盖最广