众所周知,中文没有所谓的「斜体字形」(italic font shape), 因此在与有斜体的西文字体配合时效果不佳。 中 有一套较复杂的字体框架,其下可以通过选择不同字体来对中、西文的斜体造成不同效果;一般的 做法,是西文斜体保持默认设置(采用 italic font),中文则使用楷体、仿宋等接近手写体的 字体来表示原希望用斜体实现的强调或引用效果。
在一般标记语言中,似乎还无法用简单的方式来实现这一效果。如在 HTML + CSS 体系下,整个元素
只能指定统一的 font-style: italic
样式规则,此时没有斜体字形的中文内容会被转换为别扭
的伪斜体。为了实现与 中相近的、在排版上也更加美观的效果,
只能走个弯路:
- 找到各应用斜体的元素(对我的网站,只会出先在
em
和blockquote
元素中,对其他人可能 更加复杂),获取其innerHTML
; - 用正则表达式将其中文部分筛出;
- 将所有中文内容包裹在一个自定义元素,通过此元素的样式表来实现字体修正。
例如,将所有 em
标签中的中文筛出,并消除伪斜体、采用楷体,只需如下的 JavaScript 代码
(在内容加载完成时执行):
var em_list = document.querySelectorAll('em')
for (item of em_list) {
var reg = /[\u4e00-\u9fa5]+/g // filter chinese (deprecated method)
item.innerHTML = item.innerHTML.replace(reg, '<kaiti>$&</kaiti>') // wrap
}
并为上面包裹时用的自定义标签 kaiti
设置如下样式:
kaiti {
font-style: normal; /* remove fake italic shape */
font-family: '楷体'; /* more and other fonts can be applied */
}
三个问题:
/\u4e00-\u9fa5/
还可靠吗?——不很可靠了,你可以搜搜看最新的中文匹配方式,现在似乎有更好的方式。我是懒人,目前未看见例外,又怕新方式在某些浏览器中不兼容(比如\p
在我习用的 Firefox 中还不支持),所以这样敷衍了事了。此外,你可以在正则匹配名单中加入中文标点、英文标点等更多内容,都是可行的。- 直接处理
innerHTML
是否安全?——这里由正则表达式操作的仅是中文内容,一般来说不会碰到文本以外的内容(除非某些元素有中文属性)。 - 移动端怎么办?——移动端系统上默认没有楷体、仿宋之类的备选字体,实在没辙。