lang
属性的意义同时发布于知乎:网页头部的声明应该是用
lang="zh"
还是lang="zh-cn"
? - 三日月 綾香的回答2020 年 7 月 16 日更新:「而中文、日文、韩文应当使用两侧对齐」改为「而中文、日文、韩文可以使用两侧对齐」,修改部分语句。
lang
属性…<p>天</p>
<p lang="zh-CN">天</p>
结果为:
天
天
这是因为本页面外层设置了 lang="ja"
,因此如果不设置 lang
属性,就会继承外层的设置,使浏览器默认使用日文字体。日文字体的「天」字上长下短,与中文习惯不符,影响用户的阅读体验。
有人会说,我当然不会把页面外层设置为日文。但是,如果页面没有设置 lang
属性,就会使用浏览器或操作系统设置的语言。用户的系统使用何种语言,是网页开发者无法控制的。
又有人会说,「天」字只有两横的长短区别,差别并不大,有必要关注吗?其实,这是很有必要的。
首先,虽然对于「天」字来说,日文字体与中文字体的差别并不大,但还有许多字差别较大,例如:
其次,即使网页使用日文字体,如果所有汉字都使用日文字体显示,达到风格上的统一,在一定程度上尚可接受。但是,许多日文字体缺少中国大陆的简体字,这些字会 fallback 到能显示大陆简体字的日文字体或大陆字体,从而出现字体混杂的问题。例如:
这种问题只需要在网页 html
标签添加属性 lang="zh-CN"
即可解决。
有人会说,为什么会有人使用日文系统浏览中文网页呢?实际上,随着国际交流与合作日益密切,出于工作和学习的原因,不少中国人会使用日文系统,也有不少日本人会浏览中文网页。而且,上述字体问题不仅会在日语环境下出现,在其他外语环境下同样会出现。因此,考虑这一问题是很有必要的。
lang="zh-CN"
, lang="zh-HK"
与 lang="zh-TW"
的差异<p lang="zh-CN">骨</p>
<p lang="zh-HK">骨</p>
<p lang="zh-TW">骨</p>
结果为:
骨
骨
骨
这是因为中国大陆「骨」上方朝左,而香港、台湾朝右;大陆、香港「骨」下方作两横,而台湾作「点挑」。设置语言属性后,浏览器分别应用了三地的字体。
lang="zh-Hans"
与 lang="zh-Hant"
的差异<p lang="zh-Hans">骨</p>
<p lang="zh-Hant">骨</p>
结果为:
骨
骨
这是因为 zh-Hans
默认使用大陆字形,zh-Hant
默认使用台湾字形。
lang="zh-HK"
与 lang="zh-Hant-HK"
有什么区别?一般情况下没有区别,因为香港是使用繁体中文的地区,所以 lang="zh-HK"
就隐含了 lang="zh-Hant-HK"
,二者的行为应该是等同的。
但是,在目前最新版的 Mozilla Firefox 中二者行为不同:
<p lang="zh-HK"><q>你好</q></p>
<p lang="zh-Hant-HK"><q>你好</q></p>
结果为:
你好
你好
这可能只是一个 bug。
lang
属性在西文中的差异<style>.upper { text-transform: uppercase; }</style>
<p class="upper" lang="en-US">shipping</p>
<p class="upper" lang="tr">shipping</p>
结果为:
shipping
shipping
这是因为土耳其文有带点与不带点两种 i 字母,带点的小写 i 对应的是带点的大写 İ。
lang="en-GB"
与 lang="en-US"
的差异<textarea lang="en-GB">center centre</textarea>
<textarea lang="en-US">center centre</textarea>
结果为:
这是因为在 Mozilla Firefox 中,拼写检查时会区分英国英语与美国英语。
lang
属性指定地区了?有人可能认为,既然 lang
属性会影响浏览器所使用的汉字字体,从而影响字形,那么只要用了相应地区的汉字字体,字形自然也就确定了,所以也就不必再指定 lang
属性了。
这种想法是不正确的。因为现代字体具有 OpenType 的 locl 特性,会根据 lang
属性改变字形。
<style>.font-k { font-family: 'Source Han Sans SC', sans-serif; }</style>
<p class="font-k">天</p>
<p class="font-k" lang="zh-CN">天</p>
结果为:
天
天
这是因为外层设置了 lang="ja"
,因此如果不设置 lang
属性,就会继承外层的设置,使浏览器默认使用日文字形。虽然 Source Han Sans SC 默认为中国大陆字形,但是由于 OpenType 的 locl 特性,也会自动变为日文字形。
有人会说,我当然不会把页面外层设置为日文。但是,需要再次重申,如果页面没有设置 lang
属性,就会使用浏览器或操作系统设置的语言。用户的系统使用何种语言,是网页开发者无法控制的。
还有一个更常见的现象是引号问题。
<div lang="en">
<p>“你好”</p>
<p lang="zh-CN">“你好”</p>
</div>
结果为:
“你好”
“你好”
这是因为 Unicode 中并不区分全角与半角引号,具体的显示效果会由于 lang
属性的不同而不同。
lang="zh"
还是 lang="zh-CN"
?从效果上看,二者并没有区别,都会使用大陆字形显示汉字。因此,设置哪个都是没有问题的。
但是,如果网页是简繁混排的,即同一网页中还会出现 lang="zh-HK"
或 lang="zh-TW"
,则为了代码的可读性与可维护性,应该使用 lang="zh-CN"
。
例如,使用楷体排版的多语言网页可以这样设置 CSS:
:lang(zh), :lang(ja), :lang(ko) { text-align: justify; }
:lang(zh-CN) { font-family: KaiTi, cursive; }
:lang(zh-TW) { font-family: DFKai-SB, cursive; }
:lang(zh-HK) { font-family: DFPHKStdKai-B5, cursive; }
西文文本不宜使用两侧对齐,否则会造成川流现象,而中文、日文、韩文可以使用两侧对齐。这时,使用 lang="zh"
,可以一次性选择所有中文变体,即所有以 zh
起始的 lang
属性。
如果将 lang="zh-CN"
改为 lang="zh"
,则上述 CSS 代码中的 lang="zh-CN"
也必须改为 lang="zh"
。在维护过程中,有可能因为维护人员的疏忽,规则之间被调换了顺序,写作:
:lang(zh), :lang(ja), :lang(ko) { text-align: justify; }
:lang(zh-TW) { font-family: DFKai-SB, cursive; }
:lang(zh-HK) { font-family: DFPHKStdKai-B5, cursive; }
:lang(zh) { font-family: KaiTi, cursive; }
这样就产生了 bug,因为这会导致 :lang(zh-TW)
与 :lang(zh-HK)
两条规则都被 :lang(zh)
覆盖。
lang="zh-Hant"
类属性,还是应该使用 lang="zh-TW"
类属性?如前文所述,这在显示效果上是没有差别的,因为 zh-Hant
默认使用台湾字形。但是,二者却有语义上的差别。
如果网页内容是一篇用现代文体写成的、使用繁体字的、讲述古代文化的文章,其地域性并不强,并不能直接看出是台湾、香港,或是其他使用繁体字的地区的文章,因此应该使用 lang="zh-Hant"
。同理,如果这样的文章使用简体字写成,其地域性并不强,并不能直接看出是来自中国大陆,还是其他使用简体字的地区,因此应该使用 lang="zh-Hans"
。
而如果网页内容是一篇与现代生活紧密相关的文章,则通常需要指明地区。这是因为不同地区的用字、用词与写作习惯均存在差异。例如,在用字上,中国大陆、香港「着」和「著」音义均不同,而台湾则一律用「著」;在用词上,中国大陆称「摩托车」,香港称「电单车」,而台湾称「机车」。这时就应该使用 lang="zh-CN"
, lang="zh-HK"
, lang="zh-TW"
等属性。
lang="zh-Hant"
使用香港或韩国字形?zh-Hant
默认使用台湾字形。但是有人会说,自己的页面就是需要设置 lang="zh-Hant"
,但是又不想使用台湾字形。这时可以使用 CSS 的 font-language-override
属性。
<style>
.glyph-hk:lang(zh-Hant) { font-language-override: "ZHH"; }
.glyph-kr:lang(zh-Hant) { font-language-override: "KOR"; }
</style>
<p lang="zh-Hant">霄</p>
<p class="glyph-hk" lang="zh-Hant">霄</p>
<p class="glyph-kr" lang="zh-Hant">霄</p>
结果为:
霄
霄
霄
font-language-override
属性的常用取值如下:
ZHS
ZHT
ZHH
KOR
JAN
cdo
, cjy
, cmn
, cnp
, cpx
, csp
, czh
, czo
, gan
, hak
, hsn
, lzh
, mnp
, nan
, wuu
, yue
等起始的属性?这有两个原因。
首先是出于兼容性的考量,因为只有一部分较新的浏览器支持这些属性。
例如,吴语维基百科设置了 lang="wuu"
。对于日文系统,在目前最新版的 Edge 浏览器中,页面会出现字体混杂的问题。
这是因为 Edge 不能识别 wuu
这类属性。由于系统语言为日语,因此 Edge 优先使用日文字体显示。Edge 默认的日文字体是 Meiryo 字体,该字体缺少中国大陆的简体字,因此 fallback 到宋体,从而出现字体混杂的问题。
当然,由于吴语维基百科使用吴语,与通常所指的汉语并不等同,因此确实需要使用 wuu
这一属性;而一般的汉语页面使用以 zh
起始的属性即可,不需要使用 cmn
。这就涉及到第二个原因。
根据中国开发者的习惯,在编写中文页面时,通常会认为页面记录的是「汉语」,而不是「官话」。这是因为在中国人通常的观念中,与「英语」、「日语」等相对的是「汉语」,而「官话」则与「粤语」、「吴语」等相对。如果页面使用以 zh
起始的属性,更能反映这样的语义。而如果编写的页面中同时出现了普通话与粤语,这时对普通话内容使用以 cmn
起始的属性,对粤语内容使用以 yue
起始的属性,是较好的选择。