根本原因是用了uni-nav-bar组件;它用view模拟导航栏,在iOS/部分Android真机上加透明度或渐变会触发Webkit渲染降级,导致文字发虚模糊,唯一解法是禁用uni-nav-bar、手写view导航栏并设navigationStyle为custom。

uni-app自定义导航栏文字发虚、模糊的直接原因
不是字体没抗锯齿,也不是你写了 opacity 或 rgba() 导致的渲染降级——根本原因是用了 uni-nav-bar 组件。它底层用 view 模拟原生导航栏,在 iOS 和部分 Android 真机上,一旦加透明度或背景渐变,Webkit 渲染管线会强制启用 subpixel antialiasing + layer compositing,结果就是文字边缘泛灰、笔画粘连、阴影错位。
放弃 uni-nav-bar,改用手写 view 导航栏结构
这是唯一能彻底避开模糊问题的做法。别试图给 uni-nav-bar 加 transform: translateZ(0) 或 will-change: opacity,这些在小程序和低端 WebView 里无效,还可能引发重绘卡顿。
- 在
pages.json中必须设"navigationStyle": "custom",否则状态栏高度、安全区、滚动吸附全乱套 - 导航栏容器要放在页面
<page>内部(不是全局组件),用<view class="nav">手写结构 - 标题文字用纯
<text>或<view>包裹,禁用任何父级opacity;背景色/渐变用background单独控制 - iOS 上若仍发虚,加
-webkit-font-smoothing: antialiased,但仅对黑底白字有效;浅底配深字建议换字体粗细(如font-weight: 500)提升清晰度
滚动时动态变色导致文字突然模糊
常见于“透明渐变导航栏”场景:监听 onPageScroll 动态改 background 和 color,但 iOS Safari 对频繁 CSS 属性切换极其敏感,尤其 rgba() 插值会让文字反复触发重绘降级。
- 别用
background: rgba(255,255,255,${alpha})做过渡,改用background: linear-gradient(rgba(...), rgba(...))配合固定opacity: 1 - 文字颜色切换不要靠 JS 实时算
rgb(),预设两套 class(如nav-light/nav-dark),用scrollTop判断临界点后直接切换 class - 临界距离别设太小(如
60),推荐120,避免滚动抖动时文字在两套样式间高频闪切 - 安卓低端机若发现 input 聚焦后导航栏文字变糊,说明层叠上下文被破坏,此时应把导航栏
z-index固定为999,且确保父<page>没设transform
状态栏文字颜色不匹配导致“看起来模糊”
这不是真模糊,是对比度崩了。比如你导航栏背景渐变成浅灰(#f5f5f5),但 iOS 状态栏文字仍是默认白色,就显得发灰、无力、像没渲染完。
- 必须主动调
uni.setStatusBarStyle('dark')或'light',不能依赖navigationBarTextStyle(它只对原生导航栏生效) - 切换时机要和导航栏背景同步:当
navBg亮度 > 200 时切'dark','light',别等onPageScroll结束再调,会有延迟感 - H5 端不支持该 API,需用
@supports (-webkit-status-bar-style: ...)包裹,否则报错 - 微信小程序中,如果用了自定义导航栏,胶囊按钮(右上角)文字颜色无法统一控制,只能接受系统默认,此时更要注意主标题与胶囊的视觉平衡
最易被忽略的一点:HBuilderX 调试器里看着正常,不代表真机 OK。iOS 微信、支付宝、鸿蒙快应用三端对文字渲染策略完全不同,务必在每台真机上滚动测试至少 30 秒,重点看快速滑动时标题是否出现瞬时虚化或断字。这不是性能问题,是 Webkit 层合成策略差异,绕不开,只能靠结构规避。


















