CSS 2.1 ::Artikel
Horizontal-Navigation mit gleitenden Hintergründen, Teil 2
Das Original dieses Textes wurde zuerst am 30. Oktober 2003 unter dem Titel Sliding Doors of CSS, Part II im Online-Magazin A List Apart veröffentlicht. Der Autor ist Douglas Bowman. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.
Einleitung
Der Artikel 'Horizontal-Navigation mit gleitenden Hintergründen, Teil 1' stellte eine neue Technik vor, mit der sich ungewöhnliche Navigationselemente erstellen lassen, einfach mit text-basiertem und semantischem Code. Falls Sie Teil 1 noch nicht gelesen haben, sollten Sie das jetzt nachholen.
Am Beginn dieser Seite wollen wir uns ein neues Szenario betrachten, bei dem es keinen 'aktuellen' Tab gibt; danach ersetzen wir unsere Schiebetüren durch ein Rollover, das mit einer einzigen Grafik auskommt, finden dann eine Lösung für das Problem der anklickbaren Fläche in IE/Win und schlagen schließlich eine andere Methode vor, um einzelne Tabs mit CSS anzusprechen. Anstelle einer kurzen Rekapitulation der Technik des ersten Teils lassen Sie uns gleich dort einsteigen, wo wir vorher abgebrochen haben.
Kein ‘aktueller’ Tab
Im Teil 1 haben wir alle die Fälle vernachlässigt, in denen kein 'aktueller' Tab vorhanden war. Das könnte zum Beispiel für die Seiten so sein, die eine Registration oder rechtliche Hinweise enthalten und sich unter keinem der gegebenen Tabs einordnen lassen. Sobald keiner unserer Tabs als 'aktueller' Tab gestaltet ist, wird die Regel, die 1 Pixel padding
unterhalb der Tabs einfügt, nicht mehr verwendet. Daher verdecken die Tabs die waagerechte Linie, die an der Unterseite der Tabs verläuft.
Die Lösung ist einfach: wir deklarieren für alle 'nicht-aktuellen' Tabs einen unteren Rahmen von 1 Pixel Breite, entfernen ihn aber wieder für den 'aktuellen' Tab:
#header li { float:left; background:url("left.gif") no-repeat left top; margin:0; padding:0 0 0 9px; border-bottom:1px solid #765; } #header #current { background-image:url("left_on.gif"); border-width:0; }
Was diese Änderung auf Seiten ohne 'aktuellen' Tab bewirkt, kann man hier sehen:
Beispiel 7.
Rollover mit nur einer Grafik
Um die Sache einfacher zu machen, haben wir uns im Teil 1 nicht mit Rollovers befasst. Jetzt, wo wir diese Technik grundsätzlich beherrschen, können wir sie mit anderen Techniken kombinieren, um das Verhalten der Tabs und ihre Verwendbarkeit zu erweitern.
Bis vor kurzem verlangten Rollover-Menüs (ob mit JavaScript oder reinem CSS) immer auch die Erstellung von zwei unterschiedlichen Grafiken: eine für den normalen Linkstatus, eine für den :hover
-Status. Um die Verzögerung bei der Ausgabe der :hover
-Grafik zu vermeiden, wurden eine Reihe von Methoden entwickelt, mit denen :hover
-Grafiken bereits vor der Verwendung in den Browser-Cache geladen werden. Petr Stanicek zeigt in seinem Artikel Fast Rollovers, No Preload Needed, wie man beide Stati (normal und :hover
) in einer einzigen Grafik zusammen fassen kann.
Für unser Beispiel vereinigen wir jetzt beide Hintergrundbilder der linken Seite übereinander in einer einzigen Grafik und wiederholen dasselbe für die Bilder der rechten Seite. Damit sind die ehemals 150 Pixel hohen Images jetzt 300 Pixel hoch. Wir haben nun nur noch 2 Grafiken, die wir 'left_both.gif' und 'right_both.gif' nennen. Für den :hover
-Status verwenden wir nun nicht mehr eine andere Grafik, sondern nutzen die Eigenschaft background-position
, um die kombinierte Grafik abhängig vom Status in die richtige Position zu schieben:
Wir fügen die Hindergrundbilder in unser Stylesheet ein, bleiben aber zunächst bei der gegenwärtigen Position:
#header li { float:left; background:url("left_both.gif") no-repeat left top; margin:0; padding:0 0 0 9px; border-bottom:1px solid #765; } #header a { float:left; display:block; background:url("right_both.gif") no-repeat right top; padding:5px 15px 4px 6px; text-decoration:none; font-weight:bold; color:#765; }
Für die Eigenschaft background-position
müssen wir zwei Werte angeben, einen für die Horizontale, einen für die Vertikale. Anders als bei Längen- oder Prozentwerten können wir hier keine Schlüsselworte kombinieren. Deshalb werden wir für den :hover
-Status Schlüsselworte ganz vermeiden. Wir verwenden 0%
, um die linke Seite des linken Bildes an der linken Seite des Durchgangs zu positionieren und 100%
, um das rechte Bild am rechten Rand des Durchgangs zu positionieren.
Da wir genau wissen, wo innerhalb der neuen Grafik der Teil für jeden Status beginnt, können wir das Hintergrundbild pixel-präzise positionieren. Die oberen 150 Pixel enthalten das Bild für den Normalstatus, die unteren 150 Pixel das Bild für den :hover
-Status. Wir schieben also die Hintergrundbilder beider Seiten mit Hilfe des Wertes -150px
um 150 Pixel nach oben. Dann fassen wir noch die Selektoren der ersten Regel zusammen, sodass wir die Textfarbe nur einmal zu spezifizieren brauchen:
#header li:hover, #header li:hover a { background-position:0% -150px; color:#333; } #header li:hover a { background-position:100% -150px; }
Die gleichen kombinierten Grafiken können wir auch für den aktuellen Tab verwenden. Auch hier verschieben wir für den :hover
-Status den Hintergrund des Normalstatus einfach nach oben:
#header #current { background-position:0% -150px; border-width:0; } #header #current a { background-position:100% -150px; padding-bottom:5px; color:#333; }
Beispiel 8 zeigt unsere neuen Rollovers in Aktion. Komplizierter müssen sie nicht sein. Damit benötigen wir nicht mehr fünf Grafiken (vier für die Tabs, eine für den Hintergrund), sondern nur noch drei (zwei für die Tabs, eine für den Hintergrund, und brauchen auch keine Images mehr im Voraus zu laden.
Wer unsere Arbeit bis hierhin im IE/Win oder IE/Mac verfolgt hat, hat sicher auch gemerkt, dass die Rollover-Effekte, die wir weiter oben eingebaut haben, nicht funktionieren. IE kann die Pseudoklasse :hover
ausschließlich auf Ankerelemente anwenden. Wenn beide Hintergründe innerhalb des Ankers liegen sollen, müssen wir ein weiteres Inline- Level- Element, z. B. span
, innerhalb des Ankers einfügen. Anschließend müssen wir alle Regeln um ein Element nach 'innen' versetzen. Die Regeln des Ankers definieren wir für den span
und die Regeln des Listenelements verschieben wir auf das Ankerelement.
Wir wollen uns jetzt nicht alle Einzelheiten ansehen, die zur Änderung des Rollover-Effekts im IE notwendig sind. Aber an der Demonstration im Beispiel 8a erkennen wir, dass es möglich ist. Wie Sie sehen, ist auch die im Teil 1 angesprochene kleine klickfreie Fläche verschwunden, weil durch die Umsetzung der Regeln der Anker jetzt jeweils einen ganzen Tab umfasst.
Oft sind Rollovers nur mehr oder weniger dekoratives Beiwerk. Einige von Ihnen werden sich jetzt denken, dass das notwendige Mehr an Code den Aufwand nicht wert ist, nur um Rollovers für den IE funktionsfähig zu machen. Andere werden meinen, dass zwei Elemente span
nur ein geringer Nachteil sind, den man in Kauf nehmen kann, damit Rollovers in allen verbreiteten Browsern funktionieren und die kleine klickfreie Fläche vermieden wird. Letztlich bleibt es aber völlig Ihnen überlassen, ob Sie ihren Code erweitern wollen oder nicht.
Lösung für die klickbare Fläche für IE/Win
Im Teil 1 haben wir unsere Beispieltabs in Block- Level- Elemente umgewandelt und ihnen mehr padding
gegeben, um die anklickbare Fläche zu vergrößern. In der Regel wird die Klickfläche durch eine besondere Hintergrundfarbe, oder in unserem Falle ein Hintergrundbild, visuell hervorgehoben. Das zeigt dem User, dass er überall auf dieser Fläche klicken kann, nicht nur auf dem Link selbst. Wenn man ein Ankerelement in den Block-Level-Status umwandelt und mit padding
versieht, vergrößert sich in den meisten Browsern die klickbare Fläche des Ankers, sodass sie Inhalt und padding
des Links abdeckt. Nicht so beim IE/Win: er vergrößert zwar die farblich hervorgehobene Fläche, die klickbare Fläche ist immer noch auf den Inhalt, ohne padding, begrenzt:
Im Teil 1 und nach dem Beispiel 8a weiter oben haben wir bereits die kleine klickfreie Fläche auf der linken Seite des Tab angesprochen, die durch die transparente Ecke hervorgerufen wurde. Im Teil 1 wurde der Punkt der begrenzten klickbaren Fläche im IE/Win aber nicht weiter behandelt. Dieser Browser (bis zur Version 6) leidet an einer ganzen Reihe von Fehlern in seiner Umsetzung der CSS-Spezifikation. Einer dieser Fehler ist der Grund für unbeabsichtigte Probleme (die aber manchmal unbemerkt bleiben) in Bezug auf Nutzbarkeit und Zugänglichkeit einer mit CSS formatierten Navigation.
Definiert man aber nun eine Breite oder eine Höhe für das Ankerelement, dehnt sich die Klickfläche auch im IE/Win wie von Geisterhand bis zur äußeren Padding
-Kante aus. Das würde aber die Flexibilität in der Größe unseres Durchganges für andere Browser beeinträchtigen. Theoretisch könnten wir auch die Breite oder Höhe für unser Beispiel in 'Ems' angeben. Damit würde die Größe der Tabs von der Textgröße abhängig. Das wäre nicht weiter schlimm, da die ja sowieso vererbt wird. Aber: sobald wir die Höhe für ein Ankerelement spezifizieren, spielt IE/Win verrückt. Und wenn wir keinen Monospace-Font verwenden, verhält sich die Breite der Tabs nicht proportional zur Breite ihrer Inhalte. Und davon, dass wir für jeden Text eine passende Breite herausfinden und diese mit jeder Textänderung ebenfalls ändern müssen, ist noch gar nicht die Rede.
Wir haben aber Glück, denn IE/Win bietet uns einen anderen Fehler an, den wir für unsere Zwecke nutzen können. Damit lässt sich auch für diesen Browser die Klickfläche vergrößern, ohne dass wir für jeden Tab eine Breite zu raten brauchen. Wir müssen nur eine Breite für den Anker definieren, die mit Sicherheit zu schmal ist. Die meisten Browser beachten die Eigenschaft width
an einem Block- Level- Element, auch wenn die Inhalte dieses Elements nicht in die vorgegebene Breite passen. Das Element schrumpft auf die spezifizierte Breite und stellt den Text des Inhalts wenn nötig außerhalb seiner Grenzen dar. IE/Win schrumpft jedoch das Element nur auf die Breite des kleinsten Textteils, der nicht mehr umgebrochen werden kann.
Das heißt, selbst wenn wir eine winzige Breite für das Ankerelement spezifizieren, z. B. 0.1em
, wird der Anker im IE/Win immer noch so breit sein wie der Text darin ist. Gleichzeitig wird IE/Win aber die klickbare Fläche auf den ganzen Tab ausdehnen:
#header a { float:left; display:block; width:.1em; background:url("right.gif") no-repeat right top; padding:5px 15px 4px 6px; text-decoration:none; font-weight:bold; color:#765; }
Diese Konstellation ist im Grunde genommen völlig sinnlos, da beide Konzepte direkt gegeneinander arbeiten. Aber es funktioniert und löst das Problem der Klickfläche für IE/Win. Wir dürfen jedoch nicht vergessen, dass andere Browser dieser Breitenangabe folgen und versuchen werden, die Breite jedes Tabs auf '0.1em
+ padding
' zurück zu schrumpfen. Wie gut, dass IE/Win bis Version 6.0 auch den Kindselektor noch nicht versteht. Wir verwenden ihn also, um die Breite für alle anderen Browser auf auto zurückzusetzen, damit alle Tabs wieder normal funktionieren:
#header > ul a {width:auto;}
Beispiel 9 löst das Problem der klickbaren Fläche des IE/Win. Seine kleinen unglücklichen IE-zentrischen Hacks sollten in allen anderen Browsern unsichtbar bleiben.
Tabs individualisieren
In allen Beispielen des Teils 1 wurde ein ID verwendet, das an ein einzelnes Listenelement angebracht wurde, am die Darstellung des 'aktuellen' Tabs zu ändern. Damit wird praktisch ein ID zwischen den Listenelementen hin und her geschoben - ein einfaches Konzept, das auch CSS-Einsteiger leicht begreifen. Es gibt aber noch eine andere Möglichkeit, den 'aktuellen' Tab zu kennzeichnen. Diese Möglichkeit ist oftmals effizienter, auch wenn der Code hierzu ein wenig erweitert werden muss.
Anstelle eines einfachen id="current"
, mit dem wir den 'aktuellen' Tab identifizieren, erhält jedes Listenelement seinen eigenen ID:
<div id="header"> <ul> <li id="nav-home"><a href="#">Home</a></li> <li id="nav-news"><a href="#">News</a></li> <li id="nav-products"><a href="#">Products</a></li> <li id="nav-about"><a href="#">About</a></li> <li id="nav-contact"><a href="#">Contact</a></li> </ul> </div>
Einem größeren umfassenden Element, wie body
, ordnen wir ebenfalls ein ID-Attribut zu. Der Wert dieses Attributs korrespondiert mit dem Abschnitt der Website, zu dem die aktuelle Seite gehört. Damit lassen sich auch spezifische Layouts für bestimmte Abschnitte realisieren. Mit diesen beiden IDs können wir das Aussehen eines bestimmten Tabs verändern, wenn es die durch den Nachkommen - Selektor definierte Bedingung erfüllt. Anstelle des Selektors #current
nutzen wir also jetzt die Kombination der Selektoren an den Elementen body
und li
, um die Bedingungen für den 'aktuellen' Tab zu definieren.
#home #nav-home, #news #nav-news, #products #nav-products, #about #nav-about, #contact #nav-contact { background-position:0% -150px; border-width:0; } #home #nav-home a, #news #nav-news a, #products #nav-products a, #about #nav-about a, #contact #nav-contact a { background-position:100% -150px; color:#333; padding-bottom:5px; }
Beispiel 10 zeigt den Effekt des Attributes id="news"
am Element body
und Beispiel 10a zeigt, was passiert, wenn das Attribut id="products"
am Element body
angebracht ist.
Weitere Ideen
Karteireiter: Möglicherweise nutzen Sie auf Ihren Seiten erweiterbare Module, die einfach einen Header und seinen Inhalt in eine Box einfassen. Wenn Sie dieses Modul nun noch von einem div
einfassen, dann haben Sie bereits die zwei Elemente zur Aufnahme der Hintergrundbilder. In diesem Fall ist es vorteilhaft, die schmale Grafik auf der rechten Seite zu haben wie im Beispiel 2. Damit könnten Sie den Beginn des Textes links völlig frei festlegen. Kreieren Sie einen Farbübergang zwischen den Grafiken und der Hintergrundfarbe des Inhalts, sodass Tab und Seiteninhalt wie eine Einheit aussehen.
Seitenlage: Wenn Sie die Höhe des Tabs grob abschätzen können (oder ein Image erstellen können, dass groß genug für die vertikale Ausdehnung ist), können Sie dieses Prinzip auch in einer auf die Seite gedrehten Lage anwenden. Die Hintergrundbilder gleiten dann nach oben und unten. Berücksichtigen Sie dabei aber, dass besonders auf kleineren Bildschirmen einige Zeilensprünge auftreten können.
Zucken beim IE: Falls Sie beim Überfahren der Grafiken im IE/Win ein leichtes Zucken oder Flackern der Bilder bemerken, kann das an den Einstellungen für den Browser-Cache liegen. Vielleicht haben Sie die Einstellungen einmal geändert, damit IE immer die neueste Version der besuchten Seiten online lädt und sie nicht aus dem Cache holt. Das bedingt, dass IE die Grafiken nicht stabil halten kann, wenn sie bei jedem Besuch der Seite neu geladen werden sollen. Der voreingestellte Wert ist hier 'automatisch'. Dabei werden die Bilder, falls vorhanden, direkt aus dem Cache geholt und damit jegliches Flackern vermieden.
Tabs mit mehreren Worten: Es kann oft einmal passieren, dass der Inhalt eines Tabs aus mehreren Worten besteht. Dann sollten Sie die Deklaration white-space:nowrap;
für das Ankerelement festlegen und damit Zeilensprünge vermeiden.
Es mag noch weitere Punkte geben, die man hier nennen könnte, Änderungen oder Varianten dieser Technik, die bereits existieren oder im Laufe der Zeit entwickelt werden. Dennoch wollen wir es hiermit erst einmal bewenden lassen. Wir hoffen, dass wir einige Wissenlücken füllen und einige Unklarheiten über Nutzen und Erweiterbarkeit der Schiebetürentechnik beseitigen konnten.
TOP
Hinweis:
Das Original dieses Textes wurde zuerst am 20. Oktober 2003 unter dem Titel Sliding Doors of CSS im Online-Magazin A List Apart veröffentlicht. Der Autor ist Douglas Bowman. Die Übersetzung erfolgte mit Genehmigung von A List Apart und dem Autor.
Translated with the permission of A List Apart Magazine and the author.