最稳解法是伪元素+transform:scaley(0.5),因border:0.5px在安卓全系及ios13以下兼容差;其原理是先画1px高伪元素,在dpr=2设备上占2物理像素,再纵向压缩一半,精准落于1物理像素,须配transform-origin、position:relative、box-sizing:border-box及pointer-events:none。

直接用 border: 0.5px 基本无效——安卓全系不认,iOS 13 以下也不稳定,别试。
为什么 transform: scaleY(0.5) 能压出真正 1 物理像素
高 DPR 设备(如 iPhone dpr=2)下,border: 1px 实际被渲染为 2 个物理像素,浏览器插值后就发虚、变粗。缩放不是视觉欺骗,而是先画一个标准 1px 高的伪元素(比如 height: 1px 或 border-bottom: 1px),再用 transform: scaleY(0.5) 把它纵向压缩一半,在 dpr=2 屏上刚好落到 1 个物理像素位置。
注意:0.5 只对 dpr=2 精准;dpr=3 应该用 scaleY(0.333),但硬写浮点数易因精度或编译器处理出错,实践中统一用 0.5 已覆盖绝大多数真机场景,更稳。
伪元素必须设 transform-origin
不设 transform-origin,缩放默认以元素中心为原点,下边框会整体上移、露出空白,上边框则下移遮盖内容——你看到的不是细线,是断开的半截线。
- 下边框:必须写
transform-origin: left bottom - 上边框:必须写
transform-origin: left top - 全边框:统一用
transform-origin: left top,同时伪元素width和height设为200%
box-sizing: border-box 和 position: relative 是硬性前提
全边框时漏掉 box-sizing: border-box,伪元素实际尺寸 = 内容宽高 + 四边各 1px 边框 → 缩放后仍溢出父容器 1px,导致角落发虚、边缘多出半像素黑线。
父元素没设 position: relative,伪元素会相对 body 定位,线上最多见的“1px 断开”“圆角处消失”,八成是这里漏了。
- 伪元素必须加
pointer-events: none,否则拦截点击/滑动 - 如果父容器有
overflow: hidden,缩放后伪元素可能被裁掉(transform不改变盒模型占位) - 单边推荐用
background-color+height: 1px,比border-bottom更不易发虚
真正难的不是写出第一版 CSS,而是每次用的时候都确认:当前设备真实 dpr 是多少、父容器有没有 overflow 或 border-radius、伪元素是否参与事件流——这些细节一漏,1px 就会断、偏、虚,而且很难在模拟器里复现。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











