← 返回 Debug 库

猫猫:移动端详情弹窗 - Unicode 性别符号跨环境渲染异常

移动端详情弹窗中的 ♂ 在本地与远端方向不同;根因是 Unicode 字形、字体环境和 CSS 旋转共同决定视觉结果,最终改用内联 SVG 固定几何形状。

2026-10-08

站点与应用UI/UX

猫猫手册移动端详情页的性别标记,在本地开发时看起来正常,部署到域名后却出现方向变成水平的问题。最终将字体依赖的 Unicode 性别字符改成内联 SVG,消除了跨环境差异。

① 现象

  • 本地开发环境的详情弹窗中,公猫性别标记按预期显示;
  • 通过域名访问的远端页面中,同一个标记出现水平放置的视觉差异;
  • 问题集中在移动端详情弹窗的性别区域,其他弹窗布局没有同步异常。

② 原始实现

渲染函数根据数据中的 gender 字段直接输出 Unicode 字符:

const symbol = gender === '公' ? '♂' : gender === '母' ? '♀' : '·';
return `<span class="drawer-gender-badge gender-${gender}"><b>${symbol}</b></span>`;

其中:

  • ♂ 是 Unicode U+2642;
  • ♀ 是 Unicode U+2640;
  • 字符编码只负责选择一个字符,不包含“向右上旋转 45°”这类几何信息。

原来的视觉方向由两部分叠加决定:

  1. 浏览器使用当前系统字体绘制 ♂ / ♀ 字形;
  2. CSS 再对公猫字符应用 transform: rotate(45deg)。

因此,源码中看到 ♂ 并不能证明最终像素一定相同;字体字形、CSS 是否命中、计算样式以及浏览器输出都需要分别确认。

③ 排查与证据

按“数据 → DOM → CSS → 构建产物 → 线上产物”的顺序检查:

  1. 数据字段为 公 时,客户端渲染函数确实生成了 gender-公 和 ♂;
  2. 本地 DOM 中性别标记是 <span> 包裹 <b>,不是图片或 SVG;
  3. CSS 只对 .drawer-gender-badge.gender-公 b 设置 rotate(45deg),Unicode 字符本身不提供旋转;
  4. 远端构建产物中曾经可以找到同一条旋转规则,因此不能简单归因于“远端漏发了 CSS”;
  5. 线上差异更可能来自字体字形与 CSS 变换组合的环境差异,或者旧缓存、选择器命中和计算样式的差异。

这类问题要区分四件事:

  • Unicode 字符是否正确传输;
  • 浏览器使用什么字体和字形绘制它;
  • CSS 规则是否匹配并进入计算样式;
  • 最终像素是否符合设计预期。

④ 修复

将三个状态都改成真正的内联 SVG:

  • 公猫:圆形加右上箭头;
  • 母猫:圆形加下方十字;
  • 未知性别:实心圆点。

SVG 路径直接描述几何形状,不再依赖:

  • 系统是否安装某个字体;
  • 不同字体对 ♂ 的字形设计;
  • Unicode 字形自身的比例和方向;
  • 对文本节点额外使用 transform: rotate(45deg)。

同时保留外层的 aria-label="性别:...",并给 SVG 设置 aria-hidden="true",避免装饰性路径重复被读屏器读取。

⑤ 验证

  • 本地详情弹窗 DOM 已确认输出 <svg>,不再输出 <b>、♂ 或 ♀;
  • SVG 的 transform 为 none,方向由路径本身固定;
  • 本地 npm run build 通过;
  • 线上 JS 已确认包含 SVG 路径,且不包含 ♂ / ♀;
  • 线上 CSS 已确认包含 SVG 样式,且不包含 rotate(45deg);
  • GitHub Pages 与 Vercel 部署均成功。

⑥ 可复用经验

凡是需要固定方向、比例和结构的图标,尤其是性别符号、箭头、状态标志等,不要把 Unicode 文本字符当成稳定的插画资源。Unicode 适合表达语义文本;需要稳定视觉结果时,优先使用内联 SVG 或其他明确的矢量路径。

排查“本地正常、远端变形”的文字图标时,优先检查:

  1. 实际 DOM 是文本、字体图标、SVG 还是图片;
  2. 字符的 Unicode code point 与字体 fallback 链;
  3. DevTools 中元素的 font-family、transform 和最终 computed style;
  4. 线上 HTML、CSS、JS 是否确实是新构建产物;
  5. 必要时用 SVG 替换字体依赖,再比较线上实际产物。