Webkrauts Logo

Webkrauts Webkrauts Schriftzug

- für mehr Qualität im Web

Hovereffekte mit CSS-Sprites

Wir haben noch nicht alle älteren Artikel nachbearbeitet. Das bezieht sich in der Regel nur auf die Codebeispiele, die noch nicht optimal dargestellt werden.

Hovereffekte mit CSS-Sprites

Bei Menüpunkten passiert es oft, dass eine Grafik nachgeladen werden muss, wenn man mit der Maus über den Link fährt. Stefan David zeigt, wie solche Hover- bzw. Mouseover-Effekte ohne unnötiges Nachladen realisiert werden können.

Hovereffekte, also eine Veränderung der Optik von Links beim Überfahren mit dem Mauszeiger (Mouseover-Effekt) sind häufig anzutreffen. Realisiert wird das meist durch den Austausch von Hintergrundgrafiken. Hierbei wird im Hover-Zustand des Links die zugewiesene Hintergrundgrafik gegen eine andere, oftmals nur farblich abweichende, ausgetauscht. Durch das nötige Nachladen der Austauschgrafik kann es je nach Online-Anbindung und verwendetem Browser zu einer kurzen oder längeren Verzögerung bei diesem Effekt kommen, die nicht wünschenswert ist.

Behoben wird dieses Problem mit der weniger bekannten aber nahezu ebenso einfachen Technik, die im Englischen unter dem Namen CSS-Sprites bekannt ist.

Ausgangslage

Wir haben eine Liste von Links, beispielsweise eine Navigation:

<ul id="examplenavi">
	<li><a href="#">Link 1</a></li>
	<li><a href="#">Link 2</a></li>

	<li><a href="#">...</a></li>
</ul>

Hovereffekte mit CSS-Sprites: BeispielgrafikFür den Hovereffekt benötigen wir nur eine Grafik, beispielsweise die hier verwendete link-bgr.png (Abb. links).

In Vorbereitung wird das Standard-Rendering der Listenelemente mit ul#navi, #navi li { margin:0; padding:0; list-style:none; } zurückgesetzt, um es ohne browserspezifische Eigenarten durch eigene Angaben ersetzen zu können. Wir stylen jedoch nicht die Listenelemente, sondern das a-Element, also den Link selbst. Da es sich bei Links um Inline-Elemente handelt, ist es für das weitere Vorgehen nötig, das a-Element mit display:block als Block-Element anzeigen zu lassen. Wir stellen so sicher, dass Angaben zu Innenabständen browserübergreifend angezeigt werden.

Die Links bekommen ein Padding, das neben dem Text genügend Platz für die Anzeige der Hintergrundgrafik lässt. Die Hintergrundgrafik wird platziert, und der Browser wird mit no-repeat angewiesen, die Grafik nicht zu wiederholen (zu kacheln).

Interessant wird es nun beim Hovern des Links: Statt die Hintergrundgrafik gegen eine andere auszutauschen, verschieben wir einfach die Position der Grafik, in diesem Beispiel vertikal um minus 54 Pixel (background-position:0 -54px). Dadurch wird der anders eingefärbte Bereich der Grafik sichtbar. Das Verschieben der Grafik erfordert kein Nachladen, da ja die Grafik bereits im Browser vorhanden ist und nur anders positioniert wird.

Hier der gesamte CSS-Code, der für diesen Effekt benötigt wird:

ul#examplenavi, #examplenavi li {
	margin:0;
	padding:0;
	list-style:none;
	width:8em;
}
#examplenavi a {
	display:block;
	padding:2px 2px 2px 12px;
	color:#03f;
	background:transparent url(link-bgr.png) 0 6px no-repeat;
}
#examplenavi a:hover {
	color:#f60;
	background-position:0 -54px;
}

Siehe das Beispiel.

Bugs

Natürlich gibt es auch bei diesem einfachen Effekt wieder Browser, die eine Sonderbehandlung benötigen. Ein Kandidat ist – richtig geraten – der Internet Explorer 6, der trotz des Umstandes, dass es sich nur um eine Grafik handelt, bei einer bestimmten Einstellung des Caches diese trotzdem nachlädt. Was beim Hovern zu Flackern führt – also das, was eigentlich vermieden werden sollte. Wir können diesem Umstand abhelfen, indem wir das Vorgehen ändern: Wir weisen dem Listitem (dem li-Element) die Hintergrundgrafik mit der Positionierung des Hover-Status zu und dem a-Element die Normalposition. Jetzt beim Hovern des Links die Hintergrundgrafik nicht verschieben sondern mit background:transparent entfernen und die Hintergrundfarbe auf transparent setzen, wodurch der schon passend positionierte Hintergrund des Listitems sichtbar wird. Wer mag, baut diese Variante in eine eigene Stylesheetdatei, die per Conditional Comments nur vom IE geladen wird. Das macht es einfach, den Hack wieder zu entfernen, wenn die Marktanteile dieses Browsers keine signifikante Größe mehr aufweisen.

Der zweite Kandidat ist der Mac-Browser Safari. Bei platzierten Hintergrundbildern tendiert dieser dazu, trotz der Angabe no-repeat die Hintergrundgrafik zu wiederholen. Wir umgehen diesen Bug, indem wir – wie in der Beispielgrafik zu sehen – die Grafik nach unten einfach verlängern. So darf der liebe Safari die Grafik ruhig wiederholen, die Nutzer sehen es aber nicht mehr. Der Bug soll in neueren Versionen des Browsers behoben sein, ich konnte ihn jedoch auch in aktuellen Installationen noch beobachten.

Anwendung von CSS-Sprites

Die Technik ist leicht für verschiedenste Hintergründe abzuwandeln. Ob man wie hier die vertikale Version der Verschiebung einsetzt oder den gleichen Effekt mit horizontaler Verschiebung (und natürlich entsprechender Grafik) erreicht, ist Geschmacksache. Mit kleiner Erweiterung ist auch noch problemlos zusätzlich ein »Visited«-Effekt zu realisieren.

Diese CSS-Sprites lassen sich nahezu unbegrenzt weiterentwickeln. Dave Shea hat bei A List Apart einen sehr guten Artikel zum Thema veröffentlicht. Mit den CSS-Sprites lassen sich äußerst interessante Effekte realisieren, beispielsweise lassen sich Image-Maps ohne das ungeliebte MAP-Element bauen. Auf die Spitze getrieben, reicht eine einzige Datei, um sämtliche Hintergrundbilder einer Website darzustellen. Wie bei anderen Techniken auch, ist hier der gesunde Mittelweg aber wohl das Beste.

Tipp: Unter spritegen.website-performance.org gibt es einen CSS-Sprite-Generator, der die Erstellung von Sprites stark vereinfacht.

Kommentare

Claude Roulet
am 20.10.2007 - 19:33

Kommentar zu:

Der zweite Kandidat ist der Mac-Browser Safari. Bei platzierten Hintergrundbildern tendiert dieser dazu, trotz der Angabe no-repeat die Hintergrundgrafik zu wiederholen.

Obwohl ich seit seinem Bestehen mit Safari arbeite, habe ich diesen Bug bei meinen eigenen Arbeiten noch nie bemerkt. Seltsam?!

Permanenter Link

.Carsten Jung
am 21.10.2007 - 12:14

Ich kan Claude Roulet nur zustimmen. Ich setze diese Technik, ein wenig abgewandelt zwar, in fast allen meinen Projekten ein, habe beim Safari alledings noch keine Probleme bemerkt. Wenn das Problem dort auftauchte, war es i.d.R. auch ein Problem bei anderen Browsern.

Permanenter Link
Stefan David

Stefan David (Autor)
am 21.10.2007 - 13:44

Der Bug habe ich mir nicht ausgedacht. Zum einen ist er mir bei einem gerade abgeschlossenen Projekt noch untergekommen, auch in der aktuellen Safari-Version, zum anderen bringt eine Google-Suche nach "safari background repeat bug" reichlich Ergebnisse, die den Bug beschreiben.

Permanenter Link

Klaus
am 21.10.2007 - 18:43

Danke für den guten Artikel.
Besonders die Idee, die Hintergrundgrafik dem Listenelement zuzuweisen, finde ich klasse. Ich habe es gleich mal - erfolgreich - in meiner Fotogalerie eingesetzt.

Permanenter Link

Claude Roulet
am 22.10.2007 - 00:00

Mir wurde unterdessen klar, in welchem Zusammenhang dieser mir bis gestern unbekannte Safari-Bug vorkommt. "Bei platzierten Hintergrundbildern tendiert" Safari nicht einfach zu diesem Bug, sondern der Fehler kommt nur in dem Zusammenhang vor, wenn das Element, zu dem das platzierte Hintergrundbild gehört, kleinere Abmessungen hat als das Bild selbst.

Unter Umständen wird das aber gar nicht sichtbar, hat aber damit zu tun.

Das verhält sich ein wenig spezifischer als der in meinem ersten Kommentar zitierte Satz aussagt.

Permanenter Link

Ansgar Hein
am 22.10.2007 - 15:07

Schöner Artikel, der die Technik und Anwendungsmöglichkeiten von CSS-Sprites schön veranschaulicht, aber auch die Probleme aufzeigt.

Permanenter Link

datenkind
am 22.10.2007 - 16:33

Sehr guter Artikel.
Der Background-Bug wurde mit der 2er-Version gefixt. Ich denke, dass Safari-Nutzer eigentlich mit der Zeit gehen und öfter mal updaten. *Glatteis* ;-)
Apple nutzt diese Technik ja selber für die globale Navigation.

Permanenter Link
Stefan David

Stefan David (Autor)
am 22.10.2007 - 16:48

Leider ist der Bug auch in aktuellen Safaris nicht vollständig behoben. Bei meinen Mac-Kollegen konnte ich den Bug auch auf 2er Safaris beobachten. Mehrere Fundstellen bei Google haben das auch bestätigt. Ich habe allerdings keine Energie, um herauszufinden, in welchen Konstellationen dieser Bug immer noch auftritt. Das sind die Hausaufgaben der Entwickler.

Bis vor wenigen Wochen waren übrigens die meisten unserer Macs noch mit dem zum OS ausgelieferten Safari ausgestattet. Erst nach Aufforderung wurden Updates gezogen. Und das, obwohl Safari der bevorzugte Browser der Kollegen ist. Das Glatteis voll erwischt, würde ich sagen ;-)

Permanenter Link

datenkind
am 22.10.2007 - 20:09

Ohje :D

Nunja, so richtig findet man auch keine Dev-Notes zu Safari (oder einfach nur ich nicht …). Zur Bugsuche geb ich dir recht. Das Beispiel der Apple-Seite zeigt ja, dass es funktioniert.

Permanenter Link

Stefan
am 28.10.2007 - 17:08

Danke für den Beitrag. Gerade für die klassischen Hovereffekte in der Navigation verwende ich diese Technik häufig. Neu ist mir allerdings, dass der IE6 teilweise Probleme macht. Meine Cache Einstellungen zeigen das beschriebene Verhalten nicht. Zukünftig werde ich diesen Aspekt aber berücksichtigen.

Die Technik eignet sich auch hervorragend, wenn man für den aktiven Zustand eines Links eine seperate Hintergrundgrafik verwenden möchte. So kann man alle drei Zustände mit einer Grafik abdecken.

Permanenter Link
Stefan David

Stefan David (Autor)
am 29.10.2007 - 10:24

Der IE-Bug tritt wohl im Zusammenhang mit der Cache-Einstellung "Bei jedem Aufruf der Seite" auf. Anscheinend wird ein Verschieben der Grafik vom IE als neuer Aufruf gewertet und er schaut dann mal sicherheitshalber nach, ob sich die Grafik nicht doch eventuell gerade eben noch verschoben hat.

Vermutlich gibt es in freier Wildbahn selten Probleme dieser Art, da die wenigsten IE-6-Nutzer an ihren Cache-Einstellungen herumspielen. Aber vielleicht stand das ja mal als Tipp in der Computer-B…d ("12 Tipps für aktuelle Daten beim Söhrfen") und es sind daher viel mehr, als wir denken?

Permanenter Link

Klaus
am 02.11.2007 - 18:25

...noch eine Schlaubergeranmerkung zu dieser Seite: sie validiert nicht :-)
alt fehlt bei einer Grafik und das p innerhalb von <blockquote></blockquote>

Permanenter Link
Stefan David

Stefan David (Autor)
am 02.11.2007 - 18:26

Ein fehlendes ALT-Attribut finde ich hier nicht - und der Validator unter w3.org auch nicht.

Ein P innerhalb von BLOCKQUOTE ist zulässig und in Strict-Varianten sogar vorgeschrieben (oder ein anderes Blockelement). Hier versucht das Wordpress-Template aber im ersten Kommentar ein BLOCKQUOTE innerhalb von P unterzubringen. Das geht natürlich nicht und verhindert so die erfolgreiche Validierung.

Permanenter Link

Eric Eggert
am 02.11.2007 - 18:51

Hallo Klaus, Stefan,

ich hatte beide Fehler bereits korrigiert. Das fehlende alt-Attribut befand sich beim Autorenfoto, der Absatz im Zitat wurde vom ersten Kommentator vergessen.

Permanenter Link

Alex
am 16.11.2007 - 10:13

Sehr schöne Idee. Hatte bereits vor längerer Zeit an etwas ähnlichem gebastelt. Aber nun eine schöne Zusammenfassung zu lesen hat mich sehr gefreut. Danke. ;)

Permanenter Link

Merchants
am 24.11.2007 - 03:38

Hab diese Art von Mouseover-Effekt gleich ausprobiert, sehr schön das ganze, kein zucken und mucken.
ich muss sagen.. da hätt ich selber drauf kommen können... (:

Danke

Permanenter Link

Achim H
am 12.12.2007 - 14:08

Besonders für Strukturen mit <li> und <a> gibt es auch noch eine etwas andere Methode.

Man erstellt in jeweils einem Element ein Hintergrundbild.

Zum Beispiel in <li> das hover-Bildchen und im Link das normale Bild. Beim Darstellen der Seite sind beide Bilder sofort vorhanden, ohne dass ein Bild nachgeladen werden müsste.

Beim Hovern wird lediglich dem Link mitgeteilt, dass es nun transparent erscheinen soll, wodurch das Hintergrundbild im übergeordneten Container sichtbar wird.

li {
background-image: url(hoverbild.format);
}
li a {
background-image: url(normalbild.format);
}
li a:hover, li a:focus {
background-image: none;
}
 
mfg Achim

Permanenter Link
Stefan David

Stefan David (Autor)
am 12.12.2007 - 14:26

@Achim: Genau das war ja oben schon beschrieben - als Hilfe für den IE6.

Permanenter Link

planepix
am 12.12.2007 - 20:18

Danke für den Artikel.

Das ganze funktioniert nur wenn ich dem Link-Tag display:block; zuweise oder?

Da ich ein Navigationsmenü mit einer fixen Breite habe und bei längeren Menübezeichnungen einen Umbruch zu lassen muss, klappt das leider nicht.

Ist hierzu ein Workaround bekannt?

Besten Dank und Gruß
planepix

Permanenter Link
Stefan David

Stefan David (Autor)
am 13.12.2007 - 10:34

Ich sehe kein Problem darin, dem A-Element display:block; zuzuweisen. Solange keine feste Höhe vorgegeben ist, passt sich die Höhe des Blocks der Textmenge an. Man sollte dann nur darauf achten, dass die Grafik genug Weißraum enthält, damit bei großer Textmenge nicht schon ein weiterer Bestandteil der Grafik sichtbar wird.

Über die fixe Breite des Navigationsmenüs kann man natürlich geteilter Meinung sein, das gehört hier aber nicht hin.

Permanenter Link

tanila
am 23.08.2008 - 19:06

Hallo,

ich habe einen CSS Sprite Generator geschrieben in PHP.
Momentan nur als command line tool.

Der Gag: Er kann die background-images durch die Sprites ersetzen. Das Sprite Image wird natürlich auch erzeugt.

http://tanila.de/smartsprite/index.php

Permanenter Link

Die Kommentare sind geschlossen.