CSS Image Rollover - Best practice
Zum Einstieg in mein neues Blog, in dem ich XHTML- und CSS-Tutorials schreiben werde, möchte ich einen Überblick über den neusten Stand beim Thema Image Rollover geben.
Sicherlich sind jedem noch die 50 Zeilen Javascript-Code bekannt, die Adobe ImageReady produziert, um Links mit grafischen Rollover zu versehen. Dabei wurde bei Mouseover über ein Grafik per Javascript der Pfad dieser Grafik durch den Pfad einer Anderen ersetzt. Die Ersatz-Grafiken müssen dabei vorher, ebenfalls per Javascript, in den Browser vorgeladen werden, damit beim Rollover keine Verzögerung auftritt. Obwohl diese Technik inzwischen veraltet ist, produziert ImageReady leider weiterhin diese Lösung.
Die Nachteile dabei sind:
- Aufspaltung der Rollover-Grafik in 2 Grafiken, dadurch müssen auch 2 HTTP-Requests abgefeuert werden um die Grafiken vom Server zu holen, was sich auf die Ladezeit der Site auswirken kann (wenn viele Rollover benutzt werden),
- 50 Zeilen Javascript zuviel,
- ImageReady bedient sich keiner externen Event-Handler, sondern platziert die Javascript-Aufrufe in den Link-Tags (mittels onmouseover, onmouseout, etc). Dies ließe sich natürlich beheben leicht beheben, doch
- der Effekt funktioniert sowieso nicht bei ausgeschaltetem Javascript (D’Oh).
Glücklicherweise gibt es eine Lösung, die ohne Javascript auskommt und dabei ohne CSS-Hacks in allen modernen Browsern funktionieren sollte.
Nehmen wir folgende Grafik:

Diese soll mit einem Rollover versehen werden, so dass sie bei Mouseover folgendes anzeigt:

Getrennt habe beide Grafiken eine Dateigröße von knapp 8 Kb und es sind 2 HTTP-Requests nötig, um beide abzurufen.
Kombinieren wir beide Grafiken in eine, indem wir die Höhe der Grafikdatei auf 200% aufziehen und die zweite Grafik unterhalb der ersten platzieren, erhalten wir folgendes:

Das Resultat: knapp 7 Kb Dateigröße, ein HTTP-Request - Ladezeit verringert, Ziel 1 erreicht.
Doch wie wird die Grafik nun eingebunden, damit nicht beide Rollover-Stati gleichzeitig zu sehen sind? Nehmen wir folgenden XHTML-Code
und fügen folgendes als CSS dazu
#meinRollover1 {
display:block;
width: 126px;
height: 151px;
background: #FFF url(rollover1.png) no-repeat top;
}
Zeile 1: Die Umstellung des Inline-Elements A auf ein Block-Level-Element bewirkt, dass wir diesem eine Höhe und Breite zuweisen können. Natürlich nehmen wir hier die Dimensionen der Grafik, als Höhe allerdings die halbe Höhe, also die ursprüngliche Höhe des Teils der Grafik, den wir anzeigen möchten. In Zeile 4 wird die Grafik dem Link dann als Hintergrundbild zugewiesen.
So weit, so gut. Wie kommt nun der Rollover-Effekt zu Stande? Glüclicherweise unterstützen alle Browser den Einsatz des Pseudolements :hover bei Links (bei anderen Elementen tut sich der IE6 immer noch schwer, ihm kann allerdings mit Einbindung der csshover.htc geholfen werden, was wiederrum dazu führt, dass das CSS-Stylesheet nicht mehr korrekt validiert).
Fügen wir also eine weitere CSS-Beschrebung ein:
#meinRollover1:hover {
background: #FFF url(rollover1.png) no-repeat bottom;
}
Eine einzige Zeile CSS reicht hier aus, um den gewünschten Effekt zu erzeugen. Die Hintergrundgrafik wird beim :hover-Status einfach unten ausgerichtet, und das Licht geht an (Beispiel).
Natürlich gib es auch Situationen, in denen man anderen Elementen als einem Link einen grafischen Rollover zuweisen möchte. Hierbei ist, wie oben schon erwähnt, zu beachten, dass nicht alle Browser :hover bei anderen Elementen wie z.B. DIV unterstützen. Hier kann man entweder A-Elemente als Layout-Elemente verwenden, sie per Javascript mittels void(0) deaktivieren und evtl. den Cursor ändern, damit der Benutzer nicht merkt, dass es sich um einen Link handelt. Dies ist aber semantsich nicht korrekt, denn in XHTML ist ein Link ein Link und sollte so verwendet werden.
Stattdessen kann man vorerst nur die Datei csshover.htc in sein Sytlesheet einbinden
html, body {
behavior:url("csshover.htc");
}
was allerdings dann kein valides CSS mehr ist, und darauf warten, dass zukünftige Browsergenerationen (Winke Winke, IE7) hier bessere Unterstützung für :hover bieten. IE7 wirklich schnell übernommen wird, hier ist das Problem nämlich gelöst.
Hallo
Ich habe diese Technik angewandt aber ein kleines problem:
wenn ich mehrere von diesen habe, stellen sie sich automatisch UNTEREINANDER. wie stelle ich sie nebeneinander?
Da die Links hier als Block-Level-Element angezeigt werden (display: block;) statt als normale Inline-Elemente, verhalten sie sich natürlich auch so, stehen also untereinander. Dies kann man wie bei jedem Block-Level-Elemet durch floating lösen (z.B. float: left; dies würde bewirken, dass die entsprechenden Elemente ihrer Reihenfolge im Quelltext nach von links nach rechts angezeigt werden).
ist dies auch möglich mit reinen html-seiten?
habe nämlich ein CMS in dem ich nicht auf den Head zugreifen kann und dementsprechend gebunden bin…
Das wird dann wohl nicht möglich sein (siehe z.B. diesen Beitrag auf mediengestalter.info). Zwar lassen sich CSS-Stile inline definieren (über das style-Attribut), aber Pseudo-Klassen wie :hover kann man so nicht anlegen.
habs jetzt trotzdem geschafft :-)
Cooler Tip! Verwende XIMS als CMS und habe es in eine bestehende css-Datei eingefügt… passt sehr fein!
Genau das habe ich gesucht. Leider gibt es ein kleines Problem: Egal welchen Browser ich benutze, der Hover-Effekt tritt erst dann ein, wenn ich mit der Maus ziemlich weit oben die Grafik berühre. Als ob nur dort ein gewisser Punkt wäre, der den Hovereffekt startet. Weiß jemand Rat?
@webbi: Bitte poste doch mal einen Link zu einem funktionierenden Beispiel, sonst kann ich dir da nicht helfen.
Nützliche Information. Werde diesen Blog öfter besuchen ;-)