ASP.NET MVC I18n – Teil 4: CSS Styles

23. Januar 2014

Der Anwender hat sich für eine Sprache entschieden, so langsam sollten wir anfangen, diese Entscheidung zu respektieren und ihm entsprechende Inhalte anbieten. Fangen wir mit CSS an…

Hinweis: Dieser Beitrag ist Teil einer Serie, die Übersicht findet sich hier.

 

CSS Styles sind jetzt nicht gerade spezifisch für ASP.NET MVC (weshalb dieser Punkt selten bis gar nicht in einschlägigen Tutorials adressiert wird). Aber zu einer internationalisierten Anwendung gehört das einfach dazu.

Andererseits kann man das als ein Symptom für eine hervorstechende Eigenschaft von ASP.NET MVC, verglichen mit klassischen WebForms, sehen: Der Entwickler hat weitaus mehr Kontrolle, aber er braucht auch ein deutlich besseres Verständnis der zugrundeliegenden Technologien, wie HTML, HTTP, CSS, … .

Meine kleine Beispielanwendung zeigt ein Hintergrundbild im Kopfbereich an:

   1: <body>

   2:     <header>

   3:         <div class="content-wrapper head">

   4:             <div class="float-right">

   5:                 <section id="login">

   6:                     @{ Html.RenderPartial("_SetPreferredCulture"); }

   7:                 </section>

   8:             </div>

   9:         </div>

  10:     </header>

Das Bild selbst kommt aus dem head style:

   1: .head { 

   2:     background-image: url('logo_en-US.png'); 

   3:     background-repeat: no-repeat; 

   4:     height: 100px; 

   5: }

Soweit ist das unabhängig von der Region.

Um das Ganze zu lokalisieren muss zunächst die Region als Information in den HTML-Inhalt aufgenommen werden. Typischerweise passiert das auf dem Wurzel-Element in der _Layout.cshtml:

   1: <!DOCTYPE html>

   2: <html lang="@UICulture" xml:lang="@UICulture">

UICulture wird uns von der View-Klasse zur Verfügung gestellt. Die Information wird im lang und xml:lang Attribute bereitgestellt (letzteres unter der Prämisse, dass das produzierte HTML XML-konform sein soll). Genau dort und nirgendwo sonst (was insbesondere auch den http-equiv Header Content-Language einausschließt) ist die empfohlene Vorgehensweise.

“The Content-Language value for an http-equiv attribute on a meta element should no longer be used. You should use a language attribute on the html tag to declare the default language of the actual text in the page.”

http://www.w3.org/International/questions/qa-http-and-lang

Damit steht uns im CSS die lang Pseudo-Klasse zur Verfügung, über die wir unterschiedliche Hintergründe bereitstellen können:

   1: .head {

   2:     background-image: url('logo_en-US.png');

   3:     background-repeat: no-repeat;

   4:     height: 100px;

   5: }

   6: :lang(de-DE) .head {

   7:     background-image: url('logo_de-DE.png');

   8: }

Fertig. Und funktionieren tut’s auch noch Zwinkerndes Smiley

Lokalisierung-5-en

Lokalisierung-5-de

Für den Hausgebrauch reicht das in der Regel.

 

Es gibt eine (glücklicherweise selten relevante) Falle:

Angenommen die aktuelle Seite ist im html tag als “de-DE” ausgewiesen, weil sie primär deutsch gehalten ist; und angenommen es gäbe einen englischsprachigen Abschnitt in einem div tag. Dann würde man das lang Attribut des entsprechenden div tags auf “en-US” setzen, etwa um eine kleine Flagge als Indikator anzuzeigen.

Sowohl die Intuition (meine zumindest), als auch die Spezifikation sind sich einig, dass der Inhalt des div tags jetzt als englisch zu interpretieren wäre. In HTML4:

“An element inherits language code information according to the following order of precedence (highest to lowest):

  • The lang attribute set for the element itself.
  • The closest parent element that has the lang attribute set (i.e., the lang attribute is inherited).

[…]”

http://www.w3.org/TR/REC-html40/struct/dirlang.html#h-8.1.2

Und in HTML5:

“To determine the language of a node, user agents must look at the nearest ancestor element (including the element itself if the node is an element) that has a lang attribute in the XML namespace set or is an HTML element and has a lang in no namespace attribute set. That attribute specifies the language of the node (regardless of its value).”

http://www.w3.org/TR/html5/dom.html#the-lang-and-xml:lang-attributes

Anders ausgedrückt: Das lang Attribut auf dem div tag überschreibt die Angabe auf dem html tag, die Sprache wechselt von Deutsch auf Englisch.

Was aber tatsächlich passiert – zumindest im Internet Explorer und Firefox – ist folgendes: Die Sprache wechselt nicht, stattdessen wird “en-US” ergänzt. Anders ausgedrückt, der Inhalt des div tags ist jetzt in beiden Sprachen vorhanden. Ergo werden auch die CSS Styles für beide Sprachen angezogen. Die Frage, welches Background-Image angezeigt wird, wird dann nicht mehr über die Sprache, sondern über die Reihenfolge der Styles im CSS entschieden.

Sicher ein seltener Sonderfall, aber wenn er auftritt kann er sehr nervig sein.