网页 CJK 竖排的最新进展

上个月关于 CSS 的一个重要的新闻是 [WebKit 开始支持 CJK 竖排](http://blog.timc.idv.tw/posts/han-vertical-writing-in-css3-and-javascript/) (通过 `-webkit-writing-mode`),而且时隔七年之后 (上一个版本还是 2003 年制定的),W3C 的 CSS 工作组也发布了新的 [CSS Writing Mode Level 3 工作草案](http://www.w3.org/TR/css3-writing-modes/),和以前的版本有较大的区别,WebKit 现在就是按照这个草案实现的竖排支持,虽然它的实现还不完整。下面简单介绍一下新草案的变化。

在原有草案中,`writing-mode` 属性是 `direction` 和 `block-flow` 属性的合成,你可以交叉地组合这两个属性,构成 `writing-mode`:比如 `lr-tb` 表示文字从左到右,块排列从上到下。而在新草案里,`block-flow` 不再是一个独立的概念,被并入了 `writing-mode` 中,新的 `writing-mode` 有以下几种选择:

* `horizontal-tb`: 默认情况,从上到下,从左到右的横排书写形式。

horizontal-tb
horizontal-tb

* `vertical-rl`: 块按从右到左排列,文字则从上到下,这是典型的直排情况。

vertical-rl
vertical-rl

* `vertical-lr`: 虽然是竖排,但块则从左到右排列。这主要用于内蒙古使用的[蒙古语](http://zh.wikipedia.org/zh/蒙古语字母)和[满语](http://zh.wikipedia.org/zh/满语)。

vertical-lr
vertical-lr

还可以注意到经过讨论,非常少用的从下往上横排书写形式 (`horizontal-bt`) 被去除了。

保留了 `direction` 属性,但它和 CSS2.1 中的效果一样,仍然用于控制文本在行内是从左到右还是从右到左书写,以及 Unicode BIDI 双向混合文字的情况。

同时,新增了一个 `text-orientation` 属性用于控制行内字符的旋转,例如在典型的中文竖排文稿中,拉丁字符应该顺时针旋转 90 度。目前的草案规定了以下这些模式:

* `vertical-right`: 默认的情况,将非文本语言的字符 (比如汉字中间嵌入的拉丁字符) 顺时针旋转 90 度,其他字符不变。
* `upright`: 不旋转上述字符,保持和其他字符一样的方向。(这是目前 WebKit 实现的做法,等于什么都没处理)
* `rotate-right`: 把所有字符都顺时针旋转 90 度。
* `rotate-left`: 把所有字符都逆时针旋转 90 度。
* `rotate-normal`: 在 `vertical-rl` 书写模式中等于 `rotate-right`,在 `vertical-lr` 中等于 `rotate-left`。
* `auto`: 除了对 SVG1 的 glyph orientation mode 支持以外,其他情况下等于 `vertical-right`。

下图中左侧是 `vertical-right`/`auto` 的效果,右侧是 `upright` 的效果:

最后,新增了 `text-combine` 属性用于控制在竖排时同一行内要塞进多个非 CJK 字符的情况,在日文排版中称为“縦中横”。它有两个选择:

* `none`: 不做特殊处理。
* `horizontal`: 在竖排情况下,首先浏览器应该尝试用对应字体中提供的专门的合并后的字形替代,如果没有,则浏览器可以尝试缩小这些字符以适应宽度,或者放弃合并。效果如图:

縦中横
縦中横

不过这个属性目前还很不成熟,仅仅初步把概念规范化了,短期内估计不会有浏览器尝试实现。此外这份草案还没考虑行内割注 (日文中称为 warichu) 的情况:

割注
割注

目前在 Mac OS X 下 WebKit 已经完整实现了这一版草案的 `writing-mode`,大部分的 bug 也都已经扫除 (其他平台的实现情况参见 [Koan-Sin Tan 的说明](http://lists.w3.org/Archives/Public/public-html-ig-zh/2010Dec/0019.html)),但是[还没开始实现](https://bugs.webkit.org/show_bug.cgi?id=48540) `text-orientation`,然而要保证可用的竖排效果,`text-orientation` 的支持是不可或缺的。