周六中午午休刚睁眼,Anyway 群里突然跳出一条求助消息,打破了宁静。

随后群友(我们就叫他阿强吧)发了一张截图,语气焦虑:“各位大佬,救命!设计师要把这个竖排文字做成古风网页,但他非说我的标点符号‘位置不对’,要我改成居中。但我怎么调都是偏右上的!”

我看了一眼图,经典的 writing-mode: vertical-rl 竖排布局。

但在简体中文环境下,浏览器默认会把逗号(,)和句号(。)、顿号(、)等渲染在字符格子的右下角

群友阿强甚至发了狠话:“设计师给了我一个他自己画的水墨风圆圈 icon,问我能不能把这个圆圈塞进去,还得跟汉字完美对齐。我用 <span> 一个个包起来调 margin 都快调吐了……”

看着哥们那堆满是 position: relative 的代码,我喝了口水,在群里回了一句:

“别硬撑了,放过 DOM 吧。这事儿得用‘偷梁换柱’法——我们需要黑掉字体文件。”

今天这篇博客,就来复盘一下这个让无数前端头秃的 “竖排标点居中” 问题,以及如何用最优雅的纯 CSS 方案完美解决它。

为什么竖排标点那么难搞?

首先要给哥们科普的是,浏览器没错。

在简体中文的排版规范(GB/T 15834)中,竖排标点确实是偏右的。而港台地区的繁体中文习惯,标点才是居中的。

普通的解决方案通常是:

  1. 改语言: 设置 <html lang="zh-TW">,骗浏览器用繁体字形渲染。

  2. 改属性: 使用 text-orientation: upright,但这会让标点不再旋转,逗号可能会变成奇怪的小蝌蚪。

但阿强遇到的需求是 “终极自定义”:设计师不想要系统的标点,他要用自己画的图标(Iconfont)来代替标点,而且必须是竖排模式,且必须自动生效(不能改 HTML 结构)。

这就涉及到了 CSS 中一个被严重低估的神器:unicode-range

核心思路:植入木马

我们的目标是: HTML 里依然写的是 <h1>你好,世界。</h1>,但用户眼里的“逗号”和“句号”,已经被我们替换成了 Iconfont 里的图标。

这需要两步走:

  1. 资源伪装:把 Iconfont 里图标的身份证号(Unicode)改掉。

  2. 拦截:用 CSS 告诉浏览器,遇到标点符号时,去加载我们的 “木马字体”。

第一步:修改 Iconfont 编码(最关键的一步)

大多数人使用 Iconfont,都是下载下来,然后用 &#xe601; 或者 class 来调用。但在这里,这招行不通。我们需要让图标“鸠占鹊巢”。

  1. 打开 IconfontIcoMoon

  2. 上传设计师那个“水墨风”的逗号和句号 SVG。

  3. 在下载字体包之前,进入编辑模式,修改它们的 Unicode 码值。

    • 找到你的逗号图标,把它的编码从默认的 e6xx 改成 ff0c(这是全角逗号 的标准身份证)。

    • 找到句号图标,把它的编码改成 3002(这是全角句号 的标准身份证)。

    • 如果是顿号,改成 3001

可以去 unicode 解码工具 处,将你要转换的文字输进去转换为 unicode 编码,以下图为例,逗号的 unicode 是 ff0c,我们直接替换 icon 的 unicode 值即可。

这一步做完,下载 woff2 文件。现在,这个字体包里的 ff0c 不再是系统的逗号,而是你的图标了。

第二步:CSS 里的“指鹿为马”

我们需要告诉浏览器一段非常具体的逻辑:

“浏览器你好,请优先加载 MyCustomPunctuation 这个字体。但是,只有当文章里出现**逗号(U+FF0C)句号(U+3002)**时,才用这个字体渲染;至于其他的汉字,请忽略这个字体,继续往后找苹方或微软雅黑。”

代码如下:

CSS

@font-face {
  font-family: "MyCustomPunctuation"; /* 给你的字体起个名字 */
  
  /* 直接引用刚才下载并改过编码的 iconfont 文件 */
  src: url('./fonts/my-modified-icons.woff2') format('woff2');
  
  /* 告诉浏览器生效范围 */
  /* U+FF0C = , */
  /* U+3002 = 。 */
  unicode-range: U+FF0C, U+3002;
  
  /* 避免文字闪烁 */
  font-display: swap;
}

/* 应用到竖排标题 */
h1 {
  writing-mode: vertical-rl;
  
  /* 字体栈排序:自定义字体在前,正常字体在后 */
  font-family: "MyCustomPunctuation", "PingFang SC", "Microsoft YaHei", sans-serif;
}

结局

阿强按照这个方法改完代码,刷新浏览器。

屏幕上,那些原本像牛皮癣一样贴在右上角的标点,瞬间变成了设计师手绘的水墨圆圈,而且端端正正地悬浮在字列的中央。

没有额外的 <span> 标签,没有复杂的 JS 计算,HTML 代码干干净净,就像什么都没发生过一样。

原理总结:

  1. Unicode Range 是一个过滤器。它让字体文件变成了“按需加载”的补丁包。

  2. 修改 Font 编码 是为了复用现有的字符输入习惯。你打出的是键盘上的逗号,屏幕上显示的是你的 Icon。

这个技巧不仅能用来做竖排标点,还能用来做什么?

  • 把网页里的所有数字换成特殊的“哥特数字字体”,而中文保持不变。

  • 把特定的英文字母(如 logo 里的 A)换成图案。

前端开发的乐趣,往往就在于这种“虽然标准不支持,但我能骗过浏览器”的瞬间。

愿你的竖排文字,永远居中,永不跑偏~