Menüleisten, Buttons etc. mit reinen CSS-Anweisungen zu realisieren hat sich längst auf breiter Front durchgesetzt, schließlich spricht eine ganze Menge dafür. Vielfach dokumentiert ist auch der Einsatz von Hintergrundbildern, mit denen sich Navigationselemente frei gestalten lassen, ohne die Zugänglichkeit des HTML-Markups damit aufzuweichen.
Der Austausch von Hintergrundbildern beim MouseOver wurde zu früheren Zeiten meist mit JavaScript realisiert, auch diese Aufgabe lässt sich dank der CSS-Pseudoklasse :hover leicht lösen. Die allermeisten der einschlägigen Artikel und Tutorials weisen dabei zurecht auf eine ärgerliche Besonderheit hin, dem Flackern (oder »Flashen«) des Bildes beim Austausch, weil es erst beim Darüberfahren mit der Maus nachgeladen wird und somit verzögert erscheint. Als Ausweg werden unterschiedliche Preloader-Modelle gehandelt, auch dieses Spiel kennen wir schon aus JavaScript-Zeiten. Der Nachteil aller Preloader: sie sind vergleichsweise aufwendig und in manchen Explorer-Umgebungen funktionieren sie nicht zuverlässig, die Bilder flackern auch noch, wenn sie längst geladen sind.
Dabei gibt es eine wesentlich einfachere Lösung, die in jedem gängigen Browser butterweich läuft und die Anzahl der beteiligten Grafiken halbiert. Als Beispiel nehmen wir eine gewöhnliche Linkliste. Bevor wir uns dem Code zuwenden, hier erst mal das Ergebnis:
Das Markup:
<ul>
<li id="main-1"><a href="ziel_1.html">Punkt 1</li>
<li id="main-2"><a href="ziel_2.html">Punkt 2</li>
<li id="main-3"><a href="ziel_3.html">Punkt 3</li>
</ul>
Im CSS werden die Menütexte aus dem Blickfeld gerückt, dann die Höhe und Breite der Punkte festgelegt, idealerweise entsprechen sie den Abmessungen des Bildes. Zum Schluss folgen die Background-Eigenschaften:
#main-1 a,
#main-2 a,
#main-3 a {
display: block;
text-indent: -2000px;
width: 170px;
height: 27px;
background: 0 0 no-repeat;
}
#main-1 a {
background-image: url(bild_1.gif);
}
#main-2 a {
background-image: url(bild_2.gif);
}
#main-3 a {
background-image: url(bild_3.gif);
}
Bei den meisten Lösungen wird nun das Bild mit :hover ausgetauscht, etwa so:
#main-1 a:hover {
background-image: url(bild_1_over.gif);
}
Bei den meisten Lösungen wird nun das Bild mit :hover ausgetauscht, etwa so:
#main-1 a:hover {
background-image: url(bild_1_over.gif);
}
In unserem Fall wird es nicht ersetzt, sondern verschoben. Der Blick auf das vollständige Bild macht es deutlich:

Zustand 1 und 2 sind beide im selben Bild enthalten, mit :hover werden lediglich die Koordinaten verschoben. In unserem Beispiel nach links, genauso gut könnte man es aber auch nach rechts, oben oder unten verschieben. Beim MouseOver ist es in jedem Fall schon geladen und flutscht folglich ohne Zicken. Da die Bilder bei allen Punkten gleich groß sind, kann die Angabe zusammengefasst werden:
#main-1 a:hover,
#main-2 a:hover,
#main-3 a:hover {
background-position: -170px 0;
}
Das ist schon die ganze Kunst. Falls Sie es nicht längst bemerkt haben: ein Praxisbeispiel dieses Prinzips sehen Sie auch rechts oben, das Hauptmenü unserer Site ist ebenfalls so aufgebaut.
#1 | rataka | 24.11.05, 07:41
du solltest mal die buttons oben rechts mit der maus abfahren…
die wo start profilprojekte und so’n krahm steht…
die flackern ohne ende im internet explorer…
#2 | Ralf Schmid | 24.11.05, 08:50
Sie werden lachen, aber das haben wir getan. Sogar auf einer ganzen Reihe verschiedener Explorer – traurig genug, dass man das muss. Flackern tut in den getesteten Versionen (5.0, 5.5, 6.0 Windows, 5 Mac) nichts, was benutzen Sie denn für eine geheimnisvolle Variante?
Übrigens müssen Sie zum Kommentieren keine E-Mail-Adresse angeben, es besteht also kein Anlass, irgendwelchen Quatsch in das Feld zu schreiben. Falls es Ihnen aber etwas gibt, können Sie das auch gerne beibehalten.
#3 | Jan | 29.11.05, 21:32
Hallo,
eigentlich ein toller Trick, den Sie da zeigen. Funktioniert im IE .5.5 auch einwandfrei.
In meinem IE 6.0.2900.2180.xpsp_sp2_gdr.050301-1519
tritt aber leider auch sehr starkes Flackern auf.
Beim IE kann man sich halt nach irgendwelchen Updates (seien es nun Windows- oder IE-Updates) nie sicher sein, ob sich nicht wieder einiges in der Render-Engine verändert hat. Microsoft schlüsselt ja leider die Updates nicht wirklich ehrlich auf…
Gruß
Jan
#4 | Ralf Schmid | 29.11.05, 23:35
Okay, die Zeichen mehren sich, dass am Explorer tatsächlich etwas faul ist. Wäre ja nicht das erste Mal. Ich befürchte allerdings, dass sich das kaum ändern lassen wird. Die vorgestellte Lösung ist sozusagen der minimalste Aufwand – nicht unbedingt für die Render-Engine, aber für das Laden des Bildes, immerhin ist es zwangsläufig schon vollständig geladen und wird nur im Ausschnitt verändert, weniger kann man dem Browser also nicht mehr zumuten. Alternative Preloader-Varianten laufen alle darauf hinaus, ein jeweiliges Zweitbild vorsorglich zu laden, um es bei Bedarf auszutauschen. Die Arbeit der Rendering-Engine bleibt absolut dieselbe, nur kommt jetzt noch die Laderei dazu. Außerdem schleppt man die doppelte Menge an Grafiken mit sich herum und bläht den Code gewaltig auf.
Warum Nachfolgeversionen aber an Dingen scheitern, die ihre Vorläufer mühelos beherrschten, muss mir gelegentlich mal jemand erklären. Trotzdem besten Dank für den Hinweis.
#5 | G.org | 19.12.05, 09:43
Das Flackern tritt im IE bei ausgeschaltetem Cache (Seite bei jedem Zugriff neu laden) auf. Kennt jemand ein Workaround?
#6 | Ralf Schmid | 19.12.05, 12:54
Stimmt, das ist die »Ursache«, allerdings nur bei Version 6, Version 5 schafft den soften Übergang. Hochgradiger Murks das Ganze, immerhin lautet die Ansage: »bei jedem Zugriff neu laden« und nicht »bei :hover neu laden«. Bezogen auf die üblichen Lösungen des Bildaustauschs wird sich daran aber nichts ändern. Einen Workaround halte ich für ziemlich aussichtslos, der einzige Trost bleibt die Tatsache, dass die meisten Menschen den Cache nicht ausgeschaltet haben.
Die an der Stelle normalerweise erfolgende IE-Hasspredigt möchte ich mir im Hinblick auf das nahende Christenfest heute mal verkneifen.
#7 | Sascha | 21.03.06, 14:07
Wie wär’s mit einem preloader in JavaScript…
#8 | NiceMarks | 26.03.06, 22:35
Ich lade die a:hover Grafiken einfach in einem versteckten Layer auf der entsprechenden Seite (display:none). Somit sind sie gecached und es tritt kein Flackern auf.
#9 | Ralf Schmid | 01.04.06, 00:19
Nun ja, wie wir in der vorangegangenen Diskussion gelernt haben, ist das Flackerproblem, das ausschließlich bei IE 6 mit ausgeschaltetem Cache auftrit, eher auf einen bizarren Umgang mit dem Cache bzw. dessen Abwesenheit zurückzuführen. Weder JS-Preloader noch display:none werden daran etwas ändern, zudem sind beide Optionen deutlich umständlicher als die hier erläuterte.
#10 | Nille | 02.08.06, 14:02
Klasse! Und wie bekommt man die li-Bulletpunkte weg?
#11 | Ralf Schmid | 03.08.06, 07:09
Bulletpunkte weg? So, zum Bespiel:
list-style-type: none;#12 | Florian | 14.08.06, 07:30
Mir ist da noch was aufgefallen… Das Menü (oben rechts) wird bei mir im IE6 6.0.2900… etwas seltsam dargestellt. zwischen den Menüpunkten von 01 bis 05 ist jeweils eine Lücke von 2px. Zwischen 00 und 01 taucht diese Lücke interessanter Weise nicht auf.
Der FF mach natürlich keinen Stress an dieser Stelle. Ich hatte mal ein ähnliches Problem auf einer Seite. Eine Lösung habe ich dafür leider bis heute nicht gefunden. Die Wege des IE…
#13 | Ralf Schmid | 15.08.06, 09:20
IE6 6.0.2900 also. Aha. Bei 6.0.2899 ist hingegen alles okay, nehme ich an? Im Ernst: verhält sich eigentlich jedes IE-Zwischenrelease anders als alle anderen? Was noch nicht mal schlimm wäre, man hat ja nichts anderes zu tun als die alle einzeln durchzuprobieren, wenn man sie denn nur parallel installlieren könnte, nicht mal das geht ja einfach so. Aber gut, dann schauen wir demnächst eben mal, ob es eine Lösung gibt, danke auf jeden Fall für den Hinweis.
#14 | Zach | 26.09.06, 23:55
Bei mir flackert (= ganz kurz aufblitzende Sanduhr am Cursor) es bei verschiedenen IE6ern, auf XP oder Win2000, auch mit eingeschaltetem Cache und tatsächlich gecacheten Buttons. Das haut in diesem Browser einfach nicht hin. Man sieht übrigens auch an der nur kurz aufflackernden Ziel-URL in Statusbalken beim drüberhovern, dass mit dieses Sache etwas nicht OK ist. Naja, hoffentlich ist das mit dem IE7 dann erledigt. Bis dahin gilt wohl: JS/DOM nehmen. Ist ja auch W3C-konform. Und wers nicht eingeschaltet hat, kriegt eben nur den Effekt nicht, was solls. Preloaden muss man dann halt noch.
#15 | Michelle | 29.09.06, 09:45
Ich habs ausprobiert, FF 1.5.0.7 macht gar nichts und bei IE 6.0.2900.2180 erscheint nur eine von den beiden Buttons, die ich gemacht habe.
Wie macht man voneinander unabhängige Buttons? Und wen sie verschieden gross sind?
Danke für die Antwort
#16 | Wolfgang | 02.11.06, 09:21
Hallo, erstmal ein positives Feedback, dass ihr euer Wissen hier weiter gebt.
Ich verwende schon seit längerem diese Methode, allerdings mit minimal anderem Code:
Wenn man nämlich diese beiden Eigenschaften zusammenfasst
(background: 0 0 no-repeat;)ändert der Internet Explorer 5.00.3700 beim hovern des Links die Position des Hintergrundes nicht und man sieht immer nur das erste Bild.
#17 | Ralf Schmid | 02.11.06, 10:56
Ah, ein neuer Beitrag für die anscheinend nicht abreißende Serie »Millionen von Extrawürsten für die Millionen unterschiedlicher Explorerfassungen«. Wie alle anderen auch zwar absolut hilfreich und insofern dankenswert, aber es darf bezweifelt werden, ob es jemals gelingen wird, alle Explorer-Fassungen halbwegs adäquat zu bedienen. Freuen wir uns auf das Jahr 2048, vielleicht sind die Kinderkrankheiten dieses trostlosen Browserquatsches ja bis dahin überstanden.
#18 | Simon | 23.11.06, 17:04
Hi, also ich würd gern wissen wie man dieses Menü “horizontal” macht.
Also dass alle buttons in einer Zeile sind. Wär lieb wenn mir jemand helfen könnte.
MfG Simon
#19 | Ralf Schmid | 04.12.06, 12:28
Um Listenpunkte nebeneinander abzubilden, müssen sie zunächst per CSS zu Inline-Elementen gemacht werden:
Weil die Links aber zuvor zu Block-Elementen gemacht wurden, um ihnen präzise bemessene Höhen- und Breitenangaben zu verleihen, brauchen die eben einen Float, z. B. so:
#20 | Simon | 23.12.06, 18:41
Vielen vielen Dank….
Es klappt wunderbar und sieht auch wunderbar aus.
#21 | Steffen B. | 08.02.07, 15:41
Der IE7 ist nahezu ein Klon des FF2.0 was die Render-Engine angeht und da dürfte es nun wirklich keine Probleme mehr geben.
Wer seinen Cache ausschaltet ist selbst schuld, wenn die Buttons flackern. Wenn man seinen Browser kastriert muss man sich nicht wundern, wenn einige Sachen nicht gehen oder bescheiden aussehen
#22 | arne rein | 22.05.08, 10:50
hallo ralf,
frage zu deiner button lösung:
das prinzip funktioniert sehr gut, aber gibt’s eine möglichkeit, die begrenzung des (langen) jpg-buttons wegzublenden?
diese begrenzung wird immer angezeigt, wenn der button angeklickt wird (gestrichelte linie). wenn man mehr als zwei statusbutton im bild hat, ragt dieser lange rand schonmal über die seite hinaus – auch bei deinen beispielbuttons. (in deinem menü oben allerdings ist er kleiner)
kann man das umgehen?
danke ;)
arne
#23 | arne rein | 22.05.08, 17:56
hallo ralf,
habe die lösung gerade selbst gefunden: die gestrichelte linie ist die ‘focus’-linie, u.a. zum besseren navigieren mit der TAB-taste (sieht man nur bei den mozilla-browsern). diese kann man mittels ‘hidefocus’ ausblenden.
da ich sie in diesem beispiel als störend empfinde, glaube ich, könnte man dies noch mit ergänzen.
mehr zum thema im selfhtml-forum:
http://forum.de.selfhtml.org/archiv/2004/10/t93176/#m562579
gruß,
arne ;)
#24 | Ralf Schmid | 27.05.08, 13:28
So liebe ich das: Fragen und Antworten gleich aus einer Hand. Warum nicht immer so?
#25 | Werner Schmidt | 24.06.08, 12:24
html { filter: expression(document.execCommand(“BackgroundImageCache”, false, true)); }
einfach die Anweisung in das externe Stylesheet des IE schreiben und das Flackern hat ein Ende.
Damit werden die Bilder auf jeden Fall im Cache gehalten