UI说“线不一样粗”:一个被忽视的移动端渲染细节
你有没有遇到过这种情况——明明代码里两个地方都写的是1px,设计师却拿着放大镜来找你,说这两根线粗细不一样?
别急着怀疑设计师的眼神,先看完这篇文章。
那个让我抓狂的下午
事情是这样的:上周我信心满满地接了一个首页列表页的开发任务,需求很简单——卡片里堆叠各种内容,用分割线区分开。这种需求太常见了,我甚至不需要思考就定下了方案:纵向板块用border-bottom,横向内容用伪元素加width。
代码写得飞快,热更新也一切正常。直到UI走查那天,设计师拿着手机截图来找我,放大了足足500倍,指着屏幕说:“你看,这两个分割线粗细不一样。”
我第一反应是:“不可能,代码里都是1px。”但放大后的截图不会说谎——确实一根细一根粗。
设计师的显微镜让我不得不正视这个问题,于是开始排查。查着查着发现,原来这两根线在代码里虽然都写着1px,但一个用的是border,另一个用的是width。表面上看都是1px,实际渲染出来却完全不同。
问题的根源:浏览器有两套渲染逻辑
要理解这个问题,先得知道一个概念——DPR,也就是设备像素比。现在的手机屏幕精度很高,比如iPhone15的DPR是3,意思是1个CSS像素等于9个物理像素。
问题出在这里:当DPR为3的时候,浏览器渲染1px的border和1px的width,走的是完全不同的两条路。
border有“特殊待遇”。浏览器会给border做亚像素计算,1px除以DPR之后得到一个很小的值,然后再智能四舍五入,最终用最少的物理像素来显示。这样渲染出来的border,1px就是真正的1px。
width就没这么幸运了。浏览器算完1px乘以DPR等于3个物理像素之后,某些渲染引擎觉得3不够“整”,干脆给你对齐到6个物理像素。结果就是,你写的width:1px,实际渲染出来是2px。
你可以这样理解:border走的是VIP通道,有专人优化;width走的是普通通道,没人管你细不细。
怎么解决这个问题
知道了原因,解决方案就很简单了:移动端的1px分割线,统一用border来实现,不要用width或height。
如果你对显示效果要求更高,还可以在分割线上加一句backface-visibility:hidden。这个属性能让分割线在页面滚动时保持清晰锐利,不会出现抖动模糊的情况,动画效果也会更流畅。
这个技巧特别适合用在需要频繁更新或者有动画效果的分割线上。
写在最后
回过头来看这个问题,其实挺有意思的。我们平时写代码总觉得px就是px,一就是一,二就是二。但移动端的渲染远比想象中复杂,同样的数值在不同场景下可能有完全不同的表现。
下次再遇到UI说“两根线不一样粗”的时候,别急着反驳,先想想是不是渲染层面的问题。毕竟,代码的“意思”和屏幕上的“样子”之间,可能隔着一个浏览器渲染引擎。
技术路上踩坑不可怕,可怕的是踩完坑还不知道为什么。希望今天的分享能让你少走一点弯路。

