使用语言属性设置样式

问题

如何将CSS和包含多种语言的HTML或XML页面中特定语言的文本进行关联?

在页面中发生语言变化时,样式经常被用来变更字体、字体大小和行高。这在处理简体中文和繁体中文时非常有用,因为即使很多字都是相同的,用户还是需要使用不同的字体。样式还有助于更好地协调混排时字体的外观,例如混排阿拉伯字母和拉丁字母的字体时。

本页讨论了执行该操作的多种方式。

快速回答

在HTML中按语言设置内容样式的最佳方法是在CSS中使用:lang选择器。例如:

:lang(ta) 	{
    font-family: Latha, "Tamil MN", serif;
    font-size: 120%;
    }

本文的剩余部分包括有关:lang的详细信息,并与其他两种方法进行了比较。

可采用的方法

当网页中的语言发生变化时,可以使用三种CSS选择器来应用样式。

  1. [lang = "..."]
  2. [lang |= "..."]
  3. :lang()

这三种方式都可以匹配HTML里的lang属性,而且所有主要浏览器都支持它们(参阅测试结果)。

[lang="..."] 选择器

lang属性的值和选择器中的值完全匹配时,用这个选择器为元素添加样式。

下面的CSS代码:

*[lang="zh"] {font-family: Kaiti, Kai, serif;}

会修改下面span元素的样式:

<p>"This is <em>English</em>" translates as <span lang="zh">这是<em>英文</em></span>.</p>

但是它不会匹配langzh-Hansspan元素,因为属性值必须与选择器值完全匹配。

[lang|="..."] 选择器

使用此选择器可以设置lang值以选择器中的值开头的元素的样式。

下面的CSS代码:

*[lang|="zh"] {font-family: Kaiti, Kai, serif;}

会修改下面span元素的样式:

<p>"This is <em>English</em>" translates as <span lang="zh-Hans">这是<em>英文</em></span>.</p>

实际上,这个选择器可以匹配任何lang值以zh语言子标签开头的元素,包括zhzh-Hantzh-TWzh-Hans-CN等。

语言值的继承

:lang和其他方法的一个显著区别是,即使语言是在该元素外部声明时,它依然可以识别元素内容的语言。

例如,假设在一份包含日语文本的英语文档中,你想使用CSS3属性来设置强调日语文字的样式,而不是使用斜体(斜体并不总是能很好地适用于日语的复杂文字)。你的样式中可能有如下规则:

em { font-style: italic; }
em:lang(ja)  { font-style: normal; text‑emphasis: dot; text‑emphasis‑position: over right; }

现在假设你有以下内容,用户代理支持:langhtml标签表明这是一个英文文档。

<p>This is <em>English</em>, but <span lang="ja">これは<em>日本語</em>です。</span></p>

你希望看到被强调的英语单词是斜体的,但被强调的日语单词没有斜体,而每个字上方有小点,如下所示:

Picture of what was just described.

本节要强调的是,使用[lang|="..."][lang="..."]选择器无法实现这种效果。如果想用这些选择器,唯一的方法是在每个日语的em标签上都声明语言。

这造成了不同选择器实用性的巨大差异。

哪种语言属性?

lang属性用于标记HTML文档中文本的语言。XML文档应使用xml:lang属性。

对于互联网媒体类型是text/html的XHTML文档,建议同时使用这两个属性,因为HTML解析器会使用lang属性,而XML解析器会使用xml:lang属性。

本文将首先介绍使用lang属性在HTML中按语言修改样式的多种方案,然后介绍如何基于xml:lang修改XML文档的样式

:lang(...) 伪类

下面的HTML片段:


<p>It is polite to welcome people in their own language:</p>
<ul>
    <li lang="zh-Hans">欢迎</li>
    <li lang="zh-Hant">歡迎</li>
    <li lang="el">Καλοσωρίσατε</li>
    <li lang="ar">اهلا وسهلا</li>
    <li lang="ru">Добро пожаловать</li>
    <li lang="din">Kudual</li>
</ul>

可有下面的样式:

body 		{font-family: "Times New Roman",serif;}
:lang(ar) 	{font-family: "Scheherazade",serif;
                 font-size: 120%;}
:lang(zh-Hant) 	{font-family: Kai,KaiTi,serif;}
:lang(zh-Hans) 	{font-family: DFKai-SB,BiauKai,serif;}
:lang(din) 	{font-family: "Doulos SIL",serif;}

希腊语和俄语使用body元素的样式。

这是设置语言片段样式的理想方法,因为当内容的语言在页面中的较早部分声明时,它是唯一可以把样式应用于元素的选择器。

:lang(zh) 将匹配语言值为zh的元素,也可以匹配更为具体的语言标签,如zh-Hantzh-Hanszh-TW

选择器:lang(zh-Hant)只能匹配语言值为zh-Hant或继承了该语言值的元素。如果用的是:lang(zh-TW),则无法匹配我们的示例文本。

与属性值开头匹配的[lang|="..."]选择器

对于我们在上一节中看到的HTML示例,CSS可写为:

body 		   {font-family: "Times New Roman",serif;}
*[lang|="ar"] 	   {font-family: "Scheherazade",serif;
                    font-size: 120%;}
*[lang|="zh-Hant"] {font-family: Kai,KaiTi,serif;}
*[lang|="zh-Hans"] {font-family: DFKai-SB,BiauKai,serif;}
*[lang|="din"]     {font-family: "Doulos SIL",serif;}

:lang不同,该选择器仅适用于带有lang属性的元素(参阅语言值的继承)。

这个选择器和[lang="..."]有显著的区别。[lang="..."]只在选择器值和属性值相同时才匹配,而这个选择器还可以匹配有横杠分隔的更具体的语言属性,所以[lang|="sl"]可以匹配sl-ITsl-nedissl-IT-nedis,而[lang|="zh-Hans"]也可以匹配zh-Hans-CN

通用的类或ID选择器

这种方法不需要匹配语言属性,而是依赖于classid属性。使用普通的CSS类或ID选择器适用于绝大多数支持CSS的浏览器,但缺点是添加属性会占用时间和带宽。

对于上面的示例,我们需要更改HTML代码,添加class属性,如下所示:


<p>It is polite to welcome people in their own language:</p>
<ul>
    <li class="zhs" lang="zh-Hans">欢迎</li>
    <li class="zht" lang="zh-Hant">歡迎</li>
    <li class="el" lang="el">Καλοσωρίσατε</li>
    <li class="ar" lang="ar">اهلا وسهلا</li>
    <li class="ru" lang="ru">Добро пожаловать</li>
    <li class="din" lang="din">Kudual</li>
</ul>

然后我们有下面的样式:

body 	{font-family: "Times New Roman",serif; }
.ar 	{font-family: "Scheherazade",serif;
         font-size: 120%;}
.zht 	{font-family: Kai,KaiTi,serif;}
.zhs 	{font-family: DFKai-SB,BiauKai,serif;}
.din	{font-family: "Doulos SIL",serif;}

在XML中使用CSS选择器和xml:lang

正如前面提到的,在解析成XML的文档中,你需要使用xml:lang属性(而不是lang属性)来指定语言信息。

使用 :lang

使用:lang很简单。如果文档被解析为HTML,则:lang选择器会匹配使用lang属性定义语言的内容。如果文档被解析为XML,则 :lang选择器将匹配带有xml:lang属性的内容,并忽略lang属性。

使用attr=和attr|=

使用这些选择器需要考虑一些其他因素。

xml:lang属性的xml:这部分表示这是在XML命名空间中使用的lang属性。CSS3命名空间描述了如何将xml:lang作为命名空间中的属性进行处理。我们需要声明名称空间,然后用竖线替换冒号。例如:

@namespace xml "http://www.w3.org/XML/1998/namespace"
*[xml|lang |= 'ar'] { ... }

或者:

@namespace xml "http://www.w3.org/XML/1998/namespace"
*[xml|lang = 'ar'] { ... }

@namespace规则都必须在所有@charset@import规则之后,并位于所有其他未被忽略的at规则和其他规则之前。另外,命名空间声明的URI必须完全正确。

回退机制

对于不支持命名空间的浏览器,你可以回退到转义字符。你不需要@namespace声明,只需要以下内容:

*[xml\:lang |= '..'] { ... }

或者:

*[xml\:lang = '..'] { ... }

请注意,在支持名称空间的浏览器(即最新的主要浏览器)里使用此方法不起作用。因此,如果有必要的话,除了使用此方法,还应使用基于命名空间的选择器。

顺便说一下

我使用了zh-Hantzh-Hans语言标签。这些语言标签并不代表特定的语言或方言。zh-Hant表示以繁体字记录的汉语。同样,zh-Hans表示以简体字记录的汉语。这可以指现代标准汉语和许多其他汉语方言。

zh-Hanszh-Hant语言标签出现之前,zh-TWzh-CN曾用于表示繁体中文和简体中文,而这并不合适,因为zh-TW表示台湾使用的汉语,尽管台湾使用的汉语方言不止一种。同样,zh-CN表示中国大陆使用的汉语口语,包括现代标准汉语和许多其他汉语方言,而不表示简体中文书写系统。zh-CN还被错误地用于表示在新加坡书写的简体中文。

如果你需要用语言标签来区分不同的汉语方言,IANA语言子标签注册中心可以提供很多汉语方言的标签。有关详细信息,请参阅HTML和XML中的语言标签