CSS的1px在高分屏上不是1物理像素,因为浏览器将1个CSS逻辑像素映射到多个物理像素(如dpr=2时为2×2,dpr=3时为3×3),导致边框发虚;border: 0.5px常失效因多数安卓浏览器和旧Safari不支持非整数边框宽,且iOS下在dpr=3设备仍模糊;伪元素+scale方案需同时满足position: relative、pointer-events: none、正确transform-origin三要素,并动态读取dpr写入data-dpr属性才能适配不同设备。

为什么CSS的1px在高分屏上不是1物理像素
因为浏览器把1个CSS逻辑像素映射到多个物理像素上——比如iPhone的dpr=2,border: 1px实际画了2×2个物理像素;iPad Pro部分型号dpr=3,就画了3×3。这不是bug,是渲染机制决定的:亚像素插值让边框发虚、变灰、不 crisp。
border: 0.5px 为什么经常失效
多数安卓浏览器和旧版Safari根本不支持非整数border-width,直接忽略或四舍五入为0;即使iOS 8+支持,border: 0.5px在dpr=3设备上仍渲染为1.5物理像素,照样模糊。硬写@media screen and (-webkit-min-device-pixel-ratio: 3) { .x { border-width: 0.333333px; } }也靠不住——Firefox不识别该媒体查询,Chrome会截断小数,且无法覆盖dpr=1.5(如Surface)等中间值。
伪元素+scale方案必须配齐的三要素
漏掉任意一项,边框就会断开、偏移、挡住点击或错位:
-
position: relative加在父容器上,否则::after无法绝对定位 -
pointer-events: none加在伪元素上,否则它会拦截所有触摸/点击 -
transform-origin: 0 0(或left top),缩放起点必须是左上角;画下边框时得用transform-origin: left bottom,否则线会往上飘半像素
真正起效的前提是动态读取dpr并注入data-dpr
硬编码transform: scale(0.5)只对dpr=2有效,遇到dpr=3或Windows缩放dpr=1.25就失效。必须用JS读取window.devicePixelRatio,四舍五入后写入根节点:document.documentElement.setAttribute('data-dpr', Math.round(window.devicePixelRatio) || 1)。然后CSS写成:[data-dpr="2"] .hairline::after { transform: scale(0.5); }、[data-dpr="3"] .hairline::after { transform: scale(0.333333); }。注意别用Math.floor——dpr=1.5应归入2x分支,而非向下取整为1x。
立即学习“前端免费学习笔记(深入)”;


















