前沿
我们最近在做 web 系统的国际化。国际化可不是提供多个语言版本的 web 界面这么简单。
打算分成几个部分陆续发布出来,现在我们从 html lang 属性开始。
lang 属性
HTML 和 XML 都使用 lang 属性指定语言标记。
HTML 的 lang 属性 :www.w3.org/TR/html4/st…
lang 设置和继承
设置
<html lang="zh">
<head>
<style>
:lang(zh) { color: red; }
:lang(en) { color: blue; }
:lang(zh) {
// 加载某些对应的字体
font-family: "XXX";
}
</style>
</head>
<body>
<p>有恒产者有恒心</p>
<p lang="en">别着急,我们会长大的<p>
</body>
</html>
复制代码
我们在 HTML 根节点上设置了语言标记,javascript 中运行 `document.documentElement.lang`
输出 HTML 中设置的zh
字符串;如果没有设置输出空字符串。设置 lang 属性的好处:
- 助攻搜索引擎
- 助攻语音合成器
- 助攻浏览器为了高质量的排版选择字体
- 助攻浏览器选择引号。比如:引号到底用英文的,还是中文的
- 助攻浏览器渲 text 节点时怎么断字,控制间距
- 助攻拼写检查器和语法检查器
lang 属性虽然指定了节点属性和节点文本内容的语言,但文本内容的语言并不一定于其有相关性。这个属性不是完全受控的,浏览器自己会以恰当的方式渲染内容。
- 你当然可以在指定了 zh 的 HTML 上写英文
- 你也可以在 p 节点上先指定 lang 属性是 en,然后在 p 节点的文本却渲染一堆希腊字符
继承
lang 属性还可以继承的,lang 属性生效的顺序是:
- 当前节点的 lang 属性
- 最近父节点的 lang 属性
- HTTP header 中的 Content-Language。比如可以在服务端配置
Content-Language: de-DE, en-CA
- 浏览器的默认值,也就是浏览器设置的显示语言
但是表格比较特殊,单元格可以继承的属性还包括一部分在第一个单元格上的属性。具体查看:www.w3.org/TR/html4/st…
那 lang 的属性到底可以设置成哪些值,这些值的规范是啥呢?这才是我们这篇文章的重点,我们接着往下看。
lang 属性值之 Tags for Identifying Languages
Tags for Identifying Languages(www.rfc-editor.org/rfc/rfc5646…) 我们称为语言标签,这是一套语法规范。
语法各个组成部分我们称为子标签,子标签是可以多种方式组合的。
那有哪些子标签呢?点击链接看详情:www.iana.org/assignments…。
还有一个方便查询子标签的工具:r12a.github.io/app-subtags…
lang 属性值的语法结构
子标签是怎么组合到一起的呢?这就是标签的语法结构:
language-extlang-script-region-variant-extension-privateuse
除了language 语言子标签外,其他都是可选的,对于可选的子标签能不用就不用。
language
语言子标签。有 2 个字母或者 3 个字母。一般是小写
%%
Type: language
Subtag: afb
Description: Gulf Arabic
Added: 2009-07-29
Macrolanguage: ar
%%
复制代码
这里的 macrolanguage 是表达 ar 这个子标签包含更细力度的子标签,当前 afb 标签就是 ar 下面的子标签。
再举一个例子,zh
就是一个 Macrolanguage(宏语言子标签),有常见更具体子标签的 zh-CH
, zh-HK
,甚至是不太常见的客家话子标签:
%%
Type: language
Subtag: hak
Description: Hakka Chinese
Added: 2009-07-29
Macrolanguage: zh
%%
复制代码
extlang(可选)
扩展子标签。3个字母。这种子标签结构里必须有 Preferred-Value 和 Prefix 表示上一级的子标签
%%
Type: extlang
Subtag: afb
Description: Gulf Arabic
Added: 2009-07-29
Preferred-Value: afb
Prefix: ar
Macrolanguage: ar
%%
复制代码
script(可选)
脚本子标签。4个字母。一般第一个字母是大写,剩下的是小写
%%
Type: language
Subtag: en
Description: English
Added: 2005-10-16
Suppress-Script: Latn
%%
复制代码
suppress-script 字段不是必然出现的,在这里是表示在使用 en
这个语言子标签的时候,你不应该使用 Latn
这种脚本子标签,因为英语文档都是用拉丁文写的。 Latn
子标签长这样:
%%
Type: script
Subtag: Latn
Description: Latin
Added: 2005-10-16
%%
复制代码
region(可选)
区域子标签。可以是2个字母或3个 UN M.49数字。一般是大写
%%
Type: region
Subtag: AT
Description: Austria
Added: 2005-10-16
%%
Type: region
Subtag: 015
Description: Northern Africa
Added: 2005-10-16
%%
复制代码
对 UN M.49 (Territory Containment(UN M.49)) 不理解的,请看这里:
UN M.49 是联合国用于地理分区和分组统计对国家及地区进行编码的文件,并不意味着这些编码和国家或领土有政治联系。中国和中国的两个行政特区在这里:
zh-Hant-HK
中国香港繁体中文;
zh-CN
中国大陆简体中文;zh-TW
中国台湾繁体中文;zh-HK
中国香港繁体中文;zh-MO
中国澳门繁体中文;zh-SG
新加坡简体中文;
en-GB
英国英语en-005
南美西班牙语
variant(可选)
变体子标签。除非你涉及到了很专业的语言领域,否则你不需要它。下面这个例子展示了斯诺文尼亚的 Nadiza 方言。Prefix 字段于指定的语言子标签(就是上节的 language 子标签),表示这个 variant 标签和 语言子标签 sl 关联。
%%
Type: variant
Subtag: nedis
Description: Natisone dialect
Description: Nadiza dialect
Added: 2005-10-16
Prefix: sl
%%
复制代码
与之想关联的语言子标签是:
%%
Type: language
Subtag: sl
Description: Slovenian
Added: 2005-10-16
Suppress-Script: Latn
%%
复制代码
extension(可选) & (可选)privateuse
privateuse 私有标签。假如一组学者正在研究一些中世纪时期的希腊文本,他们可能会使用一些私人子标签来识别这些文本中不同的使用风格。el 是希腊语的语言子标签。那可以这样设计一个私有子标签:x-attic
,和语言子标签组合成: el-x-attic
。设计的规则是:
- 以 x 开头并用“-”和其他子标签隔开
- 私人子标签必须由字母和数字组成,不能超过 8 个字符
- x 后面的必须被视为私人使用
一般不建议使用私有子标签。
extension 是可以自定义的扩展子标签,extlang 可以认为是官方的扩展标签。 de 是德语语言子标签,那我们可以这样定义一个扩展标签: a-value
。设计的规则是:
- 不以 x 开头,x 是专门给私有子标签用的
- 每个扩展子标签必须是 2-8 个字符,每个扩展子标签用 “-” 分隔
- 每个单子标签最多出现一次。
a-bbb-a-ccc
a 出现 2 次,无效;a-bbb-xa-ccc
有效 - 扩展子标签忽略大小写,推荐使用小写
Grandfathered(可选) & redundant(可选)
redundant 标签是冗余子标签,因为现在可以通过组合当前维护的子标签达到同样的目的。
Grandfathered 标签是向后兼容用的,是老的子标签,这些标签不能完全由当前维护的子标签组合而来。
Type: grandfathered
Tag: art-lojban
Description: Lojban
Added: 2001-11-11
Deprecated: 2003-09-02
Preferred-Value: jbo
%%
复制代码
Deprecated 表示当前这个子标签过期了,应该去查看 Preferred-Value 这个属性对应的子标签。
Preferred-Value 则表示,你可以使用jbo
语言子标签来代替 grandfathered
老标签。