最稳解法是::after伪元素配合transform:scaleY(0.5),因dpr=2时1px被渲染为2物理像素而变粗;需父元素position:relative、transform-origin:0 100%、height:1px+background-color、pointer-events:none及-webkit前缀,并用媒体查询适配dpr=3。

直接用 ::after 伪元素 + transform: scaleY(0.5) 是目前最稳的解法,不是“能用”,而是“必须这么写才不翻车”。
为什么 border: 1px 在手机上变粗?
这不是 CSS 写错了,是设备像素比(dpr)在起作用:iPhone 8/12/14 等多数机型 window.devicePixelRatio === 2,你写的 1px 会被浏览器原样铺满 2 个物理像素——它没模糊,就是实打实的 2 物理像素宽。硬写 border-width: 0.5px 在旧版安卓 WebView(如 UC、QQ 浏览器)里直接被当 0px 忽略;viewport 缩放又会连带搞乱字体、点击热区,不可控。
::after + scaleY(0.5) 怎么写才不偏位?
缩放本身很简单,错位才是高频翻车点。关键不在 scaleY(0.5),而在定位锚点和父容器约束:
- 父元素必须设
position: relative,否则::after会相对于body定位,一动就飘 -
transform-origin必须显式写成0 100%(左下角),不能只写bottom—— Safari 某些版本会失效 - 伪元素推荐用
height: 1px+background-color,别用border-bottom: 1px,后者缩放后易糊且受盒模型干扰 - 务必加
pointer-events: none,否则某些安卓 WebView 下伪元素会拦截点击事件 - 要加
-webkit-transform和-webkit-transform-origin前缀,iOS 12–15 对无前缀属性支持不稳定
四边都想要 1px 边框,scale(0.5) 为什么总出问题?
单边用 scaleY 或 scaleX 没问题,但四边一起缩放必须整体处理,否则布局会崩:
立即学习“前端免费学习笔记(深入)”;
-
::after尺寸设为width: 200%、height: 200%,画border: 1px solid #000,再transform: scale(0.5) -
transform-origin改为0 0(左上角),确保缩放锚点稳定 - 必须显式声明
box-sizing: border-box,否则默认content-box会让边框外扩,缩放后位置飘移 - 父容器若有
overflow: hidden,缩放后伪元素可能被裁掉(因缩放基于原始尺寸计算) -
content必须是非空字符串(哪怕只是''),且background-color或border-color必须显式指定——它无法继承父级颜色
dpr=3 场景怎么兜底?
scale(0.5) 只覆盖 dpr=2;dpr=3(如 iPhone 12+/15 Pro)建议用媒体查询兜底:@media (-webkit-min-device-pixel-ratio: 3) 内改用 scale(0.333),但 Safari 渲染不稳定,更推荐 fallback 到 box-shadow 或 linear-gradient。真正容易被忽略的是:圆角场景下,别在伪元素上直接设 border-radius,改用父容器 overflow: hidden 裁剪更可靠。


















