直接用::after伪元素+transform:scaleY(0.5)是最稳解法,因border:1px在DPR≥2设备上会渲染为2+物理像素而变粗;需父元素position:relative、transform-origin:0 100%防偏位,且伪元素用height:1px+scaleY(0.5)而非border属性。
直接用 ::after 伪元素 + transform: scaleY(0.5) 是目前最稳、最可控的解法,比硬写 0.5px 或改 viewport 更可靠。
border: 1px?在 DPR=2 的 iPhone 上,1 CSS 像素 = 2 物理像素,border: 1px 实际渲染出 2 物理像素宽,肉眼明显变粗。DPR=3 设备更甚。浏览器不会自动“降采样”边框,它只是把 1px 拉伸到对应物理像素数上。
常见错误现象:
border-bottom: 1px solid #eee,但在真机上看起来像 2px 粗的灰线0.5px 直接声明,结果部分安卓 WebView(尤其旧版)根本不识别,直接当 0px 渲染成无边框viewport 缩放后,整个页面字体、间距全乱,得重调所有尺寸::after + scaleY(0.5) 怎么写才不偏位?关键不在缩放本身,而在定位基点和父容器约束。缩放会以默认原点(中心)为轴心,导致伪元素下移或上浮。
立即学习“前端免费学习笔记(深入)”;
position: relative,否则 ::after 的 absolute 定位失效transform-origin 必须显式设为 0 100%(左下角),才能让 scaleY(0.5) 从底部向上压缩,不破坏对齐height 写 1px 或 2px 都行,但推荐写 1px + scaleY(0.5),语义更清晰border 属性画伪边框——它受盒模型影响,缩放后内容区可能被挤示例(底部单边):
.line-bottom { position: relative;}.line-bottom::after { content: ''; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background-color: #ddd; transform: scaleY(0.5); transform-origin: 0 100%;}
scale(0.5) 会把内容压扁吗?不会压扁内容,但会干扰盒模型——如果直接给元素加 border: 2px 再缩放,border 仍计入 width/height,导致内容区变窄。
border: 1px,再整体 scale(0.5)
box-sizing: border-box,否则缩放后边框位置飘移transform-origin 改为 0 0(左上角),确保缩放锚点稳定scaleY 支持弱,四边场景统一用 scale(0.5) 更稳妥示例(四边):
.border-all { position: relative;}.border-all::after { content: ''; position: absolute; top: 0; left: 0; width: 200%; height: 200%; border: 1px solid #e5e5e5; transform: scale(0.5); transform-origin: 0 0; box-sizing: border-box;}
scaleY(0.333)?理论上要,但实际收益有限,还增加维护成本。
scaleY(0.5) 渲染已足够锐利,人眼几乎无法分辨与真实 1px 的差异@media (-webkit-min-device-pixel-ratio: 3) 后,部分 Android 机型误报 DPR=3,反而导致边框过细甚至消失window.devicePixelRatio 后动态加 class,但日常项目没必要真正容易被忽略的是:伪元素的 background-color 或 border-color 在深色模式下可能对比度不足,记得同步检查暗色适配。