Stylen anhand von Sprachattributen

Zielgruppe: XHTML/HTML-Autoren (die Web-Editoren/Texteditoren oder Scripte benutzen), Script-Entwickler (PHP, JSP u.a.), CSS-Entwickler und alle, die Sprachinformation dazu nutzen möchten, spezielle CSS-Stile auf das Markup anzuwenden

Frage

Wie kann man am besten einen Text in einer bestimmten Sprache innerhalb eines mehrsprachigen HTML- oder XML-Dokuments mit CSS formatieren?

Hintergrund

Gewöhnlich werden Darstellungsangaben dazu genutzt, die Änderung von Schriftarten, Schriftgrößen und Zeilenhöhen zu regeln, wenn sich die Sprache innerhalb eines Dokuments ändert. Das kann besonders bei vereinfachtem bzw. traditionellem Chinesisch nützlich sein, wo die Leser verschiedene Schriftarten bevorzugen, auch wenn viele gleiche Zeichen verwendet werden. Es kann auch nützlich sein, um schriftspezifische Schriftarten miteinander harmonieren zu lassen, bspw. wenn man arabische und lateinische Schrift mischt.

Dieser Artikel zeigt, welche Möglichkeiten es gibt, dies am besten zu tun.

Kurze Antwort

Die beste Methode, Inhalte in HTML anhand ihrer Sprache zu stylen, ist die Verwendung des :lang-Selektors im CSS-Stylesheet. Zum Beispiel:

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

Der Artikel geht im Weiteren genauer auf :lang ein und vergleicht das mit zwei anderen Ansätzen. Außerdem werden Folgen für Dokumente betrachtet, die als application/xhtml+xml ausgeliefert werden.

Ausführliche Antwort

Es gibt vier Möglichkeiten, um mit CSS verschiedene Stile für verschiedene Sprachen innerhalb eines mehrsprachigen Dokuments zuzuweisen. Nach der bevorzugten Verwendung geordnet sind dies:

  1. der Pseudoklassen-Selektor :lang(…)
  2. ein Selektor [lang|="…"], der mit dem Beginn des Werts eines Sprachattributs übereinstimmt
  3. ein Selektor [lang="…"], der genau mit dem Wert eines Sprachattributs übereinstimmt
  4. ein generischer Klassen- oder ID-Selektor

Für Informationen zur Unterstützung dieser Selektoren siehe diese Testergebnisse.

Im Folgenden wird anhand von Beispielen erklärt, worin sich diese Selektoren in ihrer Verwendung unterscheiden.

Vererbung von Sprachangaben

Ein bedeutender Unterschied zwischen :lang und den anderen Methoden besteht darin, dass damit auch dann die Sprache des Inhalts beachtet wird, wenn diese außerhalb des betreffenden Elements angegeben wurde.

Nehmen wir beispielsweise an, dass japanischer Text innerhalb eines deutschen Dokuments hervorgehoben werden soll, und zwar mit speziellen asiatischen CSS3-Eigenschaften, nicht durch Kursivschrift (was sich bei den komplexen japanischen Schriftzeichen nicht anbietet). Dazu könnten folgende Regeln im Stylesheet stehen:

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

Die Eigenschaften text-emphasis und text-emphasis-position werden im aktuellen Arbeitsentwurf von CSS3 Text Decoration spezifiziert; Änderungen sind möglich, bevor der Entwurf zur Empfehlung wird.

Nehmen wir weiterhin an, dass wir folgendes Markup haben, dass der Browser :lang unterstützt und dass im html-Tag angegeben wurde, dass es sich um ein deutschsprachiges Dokument handelt.

<p>Das ist <em>Deutsch</em> und <span lang="ja">これは<em>日本語</em>です。</span></p>

Der hervorgehobene deutsche Text sollte kursiv gesetzt sein, das hervorgehobene japanische Wort jedoch nicht, dafür aber mit kleinen Punkten über jedem Zeichen, in etwa so:

Bild des eben Beschriebenen

Beachten Sie, dass dies mit den Selektoren [lang|="…"] oder [lang="…"] nicht möglich wäre. Damit diese ansprechen, müsste die Sprache explizit bei jedem japanischen em-Tag angegeben sein.

Das ist ein entscheidender Unterschied in der Anwendbarkeit dieser Selektoren.

Welches Sprachattribut man verwenden sollte

Das lang-Attribut dient zur Angabe der Sprache von Text, der als HTML ausgeliefert wird. Bei Text, der als XML ausgeliefert wird, sollte man das xml:lang-Attribut verwenden.

Für XHTML, das als text/html ausgeliefert wird, wird empfohlen, beide Attribute zu verwenden, denn der HTML-Parser wertet das lang-Attribut aus. Wenn der Inhalt hingegen als XML verarbeitet wird, verwendet der XML-Parser das xml:lang-Attribut.

Dieser Artikel behandelt zuerst die verschiedenen Möglichkeiten, in HTML unter Verwendung des lang-Attributs abhängig von der Sprache zu stylen. Danach folgt ein Abschnitt über das Stylen von XML-Dokumenten unter Verwendung des xml:lang-Attributs.

Der Pseudoklassen-Selektor :lang(…)

Das HTML-Fragment

<p>Es ist eine nette Geste, Menschen in ihrer Muttersprache zu begrüßen:</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>
                

könnte folgendermaßen gestylt werden:

body 		{font-family: "Times New Roman", serif;}
:lang(ar) 	{font-family: "Traditional Arabic", serif; font-size: 120%;}
:lang(zh-Hant) 	{font-family: PMingLiU,MingLiU, serif;}
:lang(zh-Hans) 	{font-family: SimSum-18030,SimHei, serif;}
:lang(din) 	{font-family: "Doulos SIL", serif;}
                

Griechisch und Russisch verwenden den Stil, der für das body-Element gesetzt wurde.

Dies ist die beste Art, anderssprachige Fragmente zu stylen, denn nur dieser Selektor kann einem Element Stile zuweisen, wenn die Sprache seines Inhalts früher in der Seite angegeben wurde.

Eine Regel für :lang(zh) passt für Elemente, für welche die Sprachangabe zh gilt. Sie passt aber auch für spezifischere Sprachangaben wie zh-Hant, zh-Hans und zh-TW.

Der Selektor :lang(zh-Hant) passt nur zu Elementen, für welche die Sprachangabe zh-Hant gilt (evtl. durch Vererbung). Wäre eine CSS-Regel für :lang(zh-TW) angegeben, würde sie im oben gegebenen Beispiel auf kein Element passen.

Ein Selektor [lang|="…"], der mit dem Beginn des Werts eines Sprachattributs übereinstimmt

Für das Markup-Beispiel aus dem vorigen Abschnitt könnte auch folgendes Stylesheet geschrieben werden:

body 		   {font-family: "Times New Roman", serif;}
*[lang|="ar"] 	   {font-family: "Traditional Arabic", serif; font-size: 120%;}
*[lang|="zh-Hant"] {font-family: PMingLiU,MingLiU, serif;}
*[lang|="zh-Hans"] {font-family: SimSum-18030,SimHei, serif;}
*[lang|="din"]     {font-family: "Doulos SIL", serif;}
                

Im Gegensatz zu :lang wirkt dieser Selektor nur auf Elemente, die ein lang-Attribut haben (siehe Vererbung von Sprachangaben).

Es gibt einen bedeutenden Unterschied zwischen diesem Selektor und [lang="…"]. Während [lang="…"] nur auf Elemente passt, bei denen die Werte im Selektor und im Attribut identisch sind, passt dieser Selektor auch auf Werte von Sprachattributen, die zusätzlich mit Bindestrich abgetrennte Werte enthalten. Deshalb passt der Selektor [lang|="sl"] auf sl-IT, sl-nedis und sl-IT-nedis, und der Selektor [lang|="zh-Hans"] passt auch auf zh-Hans-CN.

Ein Selektor [lang="…"], der genau mit dem Wert eines Sprachattributs übereinstimmt

Die dritte Methode zur Angabe von Stilen ist die Verwendung von Attributselektoren, die genau zu dem Attributwert passen.

Im Gegensatz zu :lang wirkt dieser Selektor nur auf Elemente, die ein lang-Attribut haben (siehe Vererbung von Sprachangaben).

Für das o.g. Markup-Beispiel könnte auch folgendes Stylesheet geschrieben werden:

body                {font-family: "Times New Roman", serif; }
*[lang="ar"] 	    {font-family: "Traditional Arabic", serif; font-size: 120%;}
*[lang="zh-Hant"]   {font-family: PMingLiU,MingLiU, serif;}
*[lang="zh-Hans"]   {font-family: SimSum-18030,SimHei, serif;}
*[lang="din"] 	    {font-family: "Doulos SIL", serif;}
                

Beachten Sie, dass in diesem Fall en nicht zu en-AU passt. Es muss exakte Übereinstimmung vorliegen.

Generische Klassen- oder ID-Selektoren

Bei dieser Methode muss gar keine Übereinstimmung mit Sprachangaben vorliegen; sie basiert auf class- bzw. id-Attributen im Markup. Die Verwendung gewöhnlicher Klassen- bzw. ID-Selektoren funktioniert in den meisten Browsern, die CSS unterstützen. Der Nachteil ist, dass das Hinzufügen der Attribute Zeit und Bandbreite kostet.

In dem Markup-Beispiel wäre der HTML-Code zu ändern, um folgende Klassen hinzuzufügen:

<p>Es ist eine nette Geste, Menschen in ihrer Muttersprache zu begrüßen:</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>
                

Dann könnte man folgendermaßen stylen:

body 	{font-family: "Times New Roman", serif; }
.ar 	{font-family: "Traditional Arabic", serif; font-size: 120%;}
.zht 	{font-family: PMingLiU, MingLiU, serif;}
.zhs 	{font-family: SimSum-18030, SimHei, serif;}
.din	{font-family: "Doulos SIL", serif;}
                

Verwendung von CSS-Selektoren für XML mit xml:lang

Wie schon erwähnt muss man in Dokumenten, die als XML verarbeitet werden, das xml:lang-Attribut anstelle des lang-Attributs zur Angabe der Sprache verwenden.

Verwendung von :lang

Die Verwendung von :lang wirft keine Probleme auf. Wenn das Dokument als HTML verarbeitet wird, sucht der :lang-Selektor nach Werten von lang-Attributen. Wird das Dokument hingegen als XML verarbeitet, sucht der :lang-Selektor nach Werten von xml:lang-Attributen und ignoriert alle Werte von lang-Attributen.

Verwendung von attr= und attr|=

Bei der Verwendung dieser Selektoren muss man zusätzlich Folgendes beachten:

Der xml:-Teil des xml:lang-Attributs bedeutet, dass es sich um das lang-Attribut aus dem XML-Namensraum handelt. Das CSS3-Namensraum-Modul gibt an, wie mit xml:lang als Attribut aus einem Namensraum zu verfahren ist. Grundsätzlich muss man den Namensraum deklarieren und dann den Doppelpunkt durch einen Senkrechtstrich ersetzen. Zum Beispiel:

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

bzw.:

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

Alle @namespace-Regeln müssen im Stylesheet nach @charset- und @import-Regeln stehen, aber vor allen anderen At-Regeln und Regelmengen. Beachten Sie auch, dass der URI in der Namensraum-Deklaration genau stimmen muss.

Fallbacks

Für Browser, die Namensräume nicht unterstützen, kann man auf Zeichenescapes zurückgreifen. Bei diesem Ansatz benötigen Sie keine @namespace-Deklaration, sondern nur Folgendes:

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

bzw.:

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

Beachten Sie aber, dass dieser Ansatz nicht in Browsern funktioniert, die Namensräume unterstützen (das betrifft die aktuellen Versionen aller gängigen Browser). Wenn Sie denken, dass es erforderlich sein sollte, verwenden Sie diesen Ansatz zusätzlich zu den Namensraum-basierten Selektoren.

Übrigens

Hier wurden die Sprachcodes zh-Hant und zh-Hans verwendet. Diese Sprachcodes repräsentieren keine bestimmten Sprachen. zh-Hant steht für in traditioneller chinesischer Schrift geschriebenem Chinesisch. zh-Hans repräsentiert in vereinfachter chinesischer Schrift geschriebenes Chinesisch. Dies kann sich auf Mandarin oder viele andere chinesische Sprachen beziehen.

Bis vor kurzem wurden die Sprachcodes zh-TW und zh-CN zur Kennzeichnung von traditioneller bzw. vereinfachter chinesischer Schrift verwendet. Eigentlich sollte zh-TW aber in Taiwan gesprochenes Chinesisch kennzeichnen, wenngleich dort mehr als eine chinesische Sprache gesprochen wird. Entsprechend kennzeichnet zh-CN in der Volksrepublik China gesprochenes Chinesisch. Dies kann sich auf Mandarin oder jede andere chinesische Sprache beziehen.

Einige moderne Webbrowser wählen bei vorhandenen Sprachkennzeichnungen zh-CN und zh-TW automatisch die Schriftarten zur Textanzeige, wenn der Entwickler der Webseite keine Schriftart angibt (siehe diese Testergebnisse für weitere Informationen).

Falls Sie Sprachkennzeichnungen zur Differenzierung zwischen verschiedenen chinesischen Sprachen benötigen: Das IANA-Register für Sprachkürzel enthält spezifischere Sprachcodes für eine Reihe chinesischer Sprachen.