Schick, nicht wahr? Funktioniert auch ohne Javascript, allerding dann aber auch ohne Überblend-Effekt. Und mit einem Minimum als HTML, eine Kelle CSS und dem Javascript-Framework mootools lässt sich das Ganze auch ganz einfach realisieren. An die Arbeit!
HTML und Grafik
Hier gibt es nicht viel zu sagen, deswegen nehme ich es vorweg – wir haben wieder das übliche Markup für eine Navigation zuzüglich eines <span>
um hinterher den HTML-Text zu verstecken.
<ul id="navi">
<li id="nav1"><a href="#"><span>Startseite</span></a></li>
<li id="nav2"><a href="#"><span>Produkte</span></a></li>
<li id="nav3"><a href="#"><span>Standorte</span></a></li>
<li id="nav4"><a href="#"><span>Kontakt</span></a></li>
</ul>
Für die Grafiken brauchen wir wieder eine Bildmatrix mit in diesem Fall zwei Zuständen pro Menüpunkt. So weit ist alles wie bei jeder Navigation, aber ab jetzt wird es interessant, denn die flashige Navigation ohne Flash funktioniert doch ein wenig anders als eine handelsübliche Matrixnavigation.
Zur Funktionsweise
Bei der normalen Matrixnavigation würden wir jetzt den <a>
die Navigrafik als Hintergrundbild verpassen, es für jeden Menüpunkt positionieren und beim Mouseover einfach per background-position
vom einen Zustand in den anderen schieben. Aber weil wir diesmal eine schicke Überblendung haben wollen, müssen wir umdenken. Unser Plan:
- Die
<li>
bekommen die Navigrafik als Hintergrundbild. Dieses wird jeweils so positioniert, dass es den normalen Zustand des Menüpunkts abbildet. - Auch die
<a>
bekommen die Navigrafik als Hintergrundbild. Dieses wird jeweils so positioniert, dass es den Mouseover-Zustand des Menüpunkts abbildet. - Beim Mouseover drehen wir einfach die Transparenz des jeweiligen
<a>
rauf und runter. So schaffen wir elegant einen einfachen Wechsel zwischen den Zuständen. - Am Ende sorgen wir mit Javascript dafür, dass dieser Wechsel eine langsame Überblendung und nicht ein plötzlicher Wechsel wird. Hat der Nutzer Javascript aus, kommt eben der normale, rein CSS-basierte Übergang zu tragen. Nicht so schön, aber genau so funktional.
CSS
Zuerst muss also die reine CSS-Funktionalität sicher gestellt werden. Das heißt, dass vor allem das Hintergrundbild der <li>
und der <a>
sitzen muss. Nichts leichter als das:
#navi li { display:block; width:128px; height:32px; background:url(navi.png) no-repeat; margin:8px 0; } #navi #nav1 { background-position:0 0; } #navi #nav2 { background-position:-128px 0; } #navi #nav3 { background-position:-256px 0; } #navi #nav4 { background-position:-384px 0; } #navi li a { display:block; width:128px; height:32px; background:url(navi.png) no-repeat; } #navi #nav1 a { background-position:0 -32px; } #navi #nav2 a { background-position:-128px -32px; } #navi #nav3 a { background-position:-256px -32px; } #navi #nav4 a { background-position:-384px -32px; }
Um zu erreichen, dass der Menüpunkt beim Mouseover sein Aussehen verändert, drehen wir einfach beim Hover den Wert für opacity
runter bzw. rauf.
#navi li a:link, #navi li a:visited { opacity:0.00001; } #navi li a:hover, #navi li a:active { opacity:1; }
Die CSS-Eigenschaft opacity
beherrschen alle modernen Browser. Für die nicht so modernen aus Redmond lässt sich aber leicht sorgen:
<!--[if IE]><style type="text/css" media="screen">
#navi li a:link, #navi li a:visited { filter:progid:DXImageTransform.Microsoft.Alpha(opacity=1); }
#navi li a:hover, #navi li a:active { filter:progid:DXImageTransform.Microsoft.Alpha(opacity=100); }
</style><![endif]-->
Und zuletzt muss noch der Text in den <span>
nach bewährter Methode versteckt werden.
#navi li a span { display:block; width:0; height:0; overflow:auto; }
Und schon haben wir eine einwandfrei funktionierende Navigation. Die ist soweit nicht ganz so elegant wie die normale Matrixnavigation, aber dafür lässt sich hier sehr leicht das Javascript für den weichen Übergang anhängen.
Javascript
Auf der Downloadseite von mootools kann man sich bequem alle Komponenten des Frameworks auswählen, die man gerade braucht. In unserem Fall sind das:
- FX.Styles
- Element.Selectors
- Window.DomReady
Der Klick auf den Download-Button liefert Code, der zwar aussieht wie Hackstück, tatsächlich aber komprimiertes Javascript ist. Dies packen wir in eine .js-Datei und fügen sie in unsere Website mit der Navigation ein. Wer sich nicht selbst die Komponenten zusammenklicken möchte und/oder keine anderen Komponenten braucht, kann sich auch gerne das Script der Beispielseite laden.
Nun müssen nur noch die Navigation und die Mootools-Effekte zusammengeführt werden. Mit einem kleinen Schnipsel Mootools-Code ist das auch schon getan:
window.addEvent('domready', function() { var list = $$('#navi a'); list.each(function(element) { var fx = new Fx.Styles(element, {duration:800, wait:false}); fx.set({'opacity': 0.00001}); element.addEvent('mouseenter', function() { fx.start({'opacity': [0.00001, 1]}); }); element.addEvent('mouseleave', function() { fx.start({'opacity': [1, 0.00001]}); }); }); });
Selbst wenn man mootools-Code noch nie gesehen hat, kann man durchaus erraten, was hier passiert… trotzdem ein paar Worte zur Erklärung:
var list = $$('#navi a');
legt die Liste der Elemente fest, die unser Script bearbeitet. Wie schon zu sehen ist, können diese dort wie über einen CSS-Selektor definiert werden – in diesem Fall sind es alle<a>
in unser Navigationsliste.- Die Zahl in
var fx = new Fx.Styles(element, {duration:800, wait:false});
legt fest, wie lang ein Übergang in Millisekunden dauert – hier 800. - Die Mootools sind schlau genug, auch die Deckkraft für den IE automatisch mitzuregeln. Um fossile Browser müssen wir uns an dieser Stelle also nicht scheren.
- Dass sowohl im CSS als auch im JS
opacity
niemals 0 ist, liegt daran, dass komplett unsichtbare Elemente nicht nur nicht mehr zu sehen sind, sondern auch nicht mehr auf Mouseover ansprechen. Deswegen muss uns 0.00001 unsichtbar genug sein.
Anpassung
Die Zahlen in fx.start({'opacity': [0.00001, 1]});
und fx.start({'opacity': [1, 0.00001]});
legen jeweils fest, dass sich der opacity
-Wert immer von 0.00001 nach 1 bzw. von 0.00001 nach 1 entwickelt. Das gilt auch dann, wenn das Element gar nicht den Startwert von 1 oder 0.00001 hat! Was das praktisch bedeutet sieht man dann, wenn man schnell mit der Maus über die Navigationspunkte fährt. Noch bevor die <a>
vollständig eingeblendet sind, beginnt schon das Ausblenden, wobei ein Sprung zur vollen opacity
stattfindet – denn das beginnt ja per Definition immer bei 1 und hört bei 0.00001 auf.
Ich persönlich finde diesen Effekt gut. Wenn ihm jemand nicht haben will, ist das leicht zu erreichen: Einfach die Von/Bis-Angaben inklusive Klammern durch einen einzigen Endwert ersetzen. Dann nämlich wird der Übergang vom gerade aktuellen opacity
-Wert aus durchgeführt. Aus fx.start({'opacity': [0.00001, 1]});
wird fx.start({'opacity': 1});
und aus fx.start({'opacity': [1, 0.00001]});
wird fx.start({'opacity': 0.00001});
. Sieht kompliziert aus, ist es aber nicht.
Kommentare (20)
Kevin ¶
10. Januar 2008, 10:40 Uhr
Kann man als Bild nicht ein animieres gif nehmen? Dann funktioniert's doch auch ohne JS.
Peter ¶
10. Januar 2008, 12:59 Uhr
Ich mir nur schwer vorstellen, wie das funktionieren könnte.
Kevin ¶
11. Januar 2008, 10:33 Uhr
Man baut die Navi mit Jpgs und tauscht die einzelnen dann bei :hover gegen ein animiertes Gifs aus. -> Button ist animiert und ohne Javascript. (Wobei man dann die kurze Browserverzögerung beim Nachladen des Hover-Bildes mit einkalkulieren muss)
Peter ¶
11. Januar 2008, 12:24 Uhr
Dann brauchst du aber gleich zwei Gifs – eins zu einblenden und eins zu ausfaden. Und dazu noch die Ladezeit... ich bin mir nicht sicher ob das wirklich so viel besser wäre. Höchstens wenn man eine Javascript-Allergie hat.
Kevin ¶
11. Januar 2008, 12:31 Uhr
Ja, Du hast wahrscheinlich Recht. War nur so eine Idee für die Anti-JS-Front. Aber Javascript ist ja im Web 2.0 nicht mehr böse. ;)
Nicole ¶
31. Januar 2008, 09:56 Uhr
Hab alles nachgebaut. Aber der JS Code springt nicht darauf an! Habe Ihn im Head extern verlinkt. Und im Body innerhalb eines script tags angesprochen (die Codeschnipsel! zum zusammenführen eingefügt)! Ich hab sicherlich was falsch gemacht. Aber was? Wär toll wenn DU mir genau erläutern kannst, wo wie js in das Dokument kommt. Denn das Tutorial ist so super, zu diesem Thema ist nämlich kaum was deutsches zu finden!
Peter ¶
31. Januar 2008, 10:05 Uhr
Das klingt eigentlich alles soweit ganz richtig. Was ich an deiner Stelle versuchen würde, ist das Javascript nicht im Body, sondern im Head zu platzieren. Wenn das nicht helfen sollte, wäre zur weiteren Diagnose ein Link zur Navi ganz hilfreich. Ich kann mich da anhand von Beschreibungen immer so schlecht reindenken.
Nik ¶
29. Februar 2008, 19:51 Uhr
Hallo Peter,
danke für dieses Tutorial, es ist wirklich schwer was in deutsch zu finden.
Ich habe eine frage, ob man das ganze auch "umdrehen" kann, bzw. ich möchte den Html text beibehalten können.
Ist es also möglich eine a class "active" bei hoover sozusagen einzublenden und bei mouseleave wieder auszublenden?
Peter ¶
29. Februar 2008, 20:01 Uhr
Wenn ich dich recht verstehe brauchst du das einfache Drop-Down-Menü mit CSS und (fast) ohne Javascript.
Nik ¶
29. Februar 2008, 20:08 Uhr
Zitat Peter:
...danke für die schnelle Antwort - aber, nein, ich wollte schon diesen "fade" effect, aber zwischen zwei css klassen bei hoover "faden" somit könnte ich den html text beibehalten
Peter ¶
29. Februar 2008, 20:24 Uhr
Ah so. Das geht auch mit diesem JS-Framework, allerdings habe ich dafür kein Tutorial zur Hand, nur ein Codebeispiel. Vielleicht kannst du dir daraus ableiten was du brauchst.
Nik ¶
29. Februar 2008, 20:42 Uhr
.. das hatte ich schon durch, aber könnte ich da statt den ganzen Style hineinzuschreiben auf eine bestehende class im css verweisen?
Irgendwie funktioniert es nämlich nicht, wenn ich versuche im mouseenter event ein Background image zu setzen.
Peter ¶
29. Februar 2008, 21:31 Uhr
Ob das mit bestehenden Klassen geht, weiß ich jetzt nicht. Und Bildwechsel beim Mousover müsste doch mit
this.style.backgroundImage = 'url(bild.jpg)'
o.Ä. machbar sein.Ich weiß nicht, ob ich dein Problem so richtig verstehe.
zeitmeister ¶
8. August 2008, 16:17 Uhr
Hallo Peter,
ich habe - wie ich hoffe - alles beachtet, doch es will bei mir nicht funktionieren.
Hast du eine Idee, woran es liegen könnte?
Ich habe alle relevanten Dateien in diesem ZIP-Archiv gepackt:
http://www.zentapher.com/wpforum/kram_02.zip
Meine Seite, für die ich deine Lösung gerne verwenden würde, findest du hier:
http://www.zentapher.com
Es geht um den Pagelink ganz oben rechts im schwarzen Balken, momentan nur per mouseover sichtbar.
Kannst du mir einen Tipp geben?
Danke im Voraus!
lowpixel ¶
17. Februar 2009, 14:01 Uhr
Sehr Sehr gute Anleitung!
Habe es soweit auch umsetzen können (noch nicht online gestellt). Würde gerne nach dem klick auf einen Button diesen aktiviert lassen! Wie würdest du das realisieren?
Peter ¶
17. Februar 2009, 15:45 Uhr
Dem Ding einfach eine andere Klasse zuweisen, entweder mit PHP o.Ä. serverseitig oder clientseitig per Javascript.
Marc A. Bonsels ¶
18. Februar 2009, 07:41 Uhr
Wer statt Mootools lieber jQuery einsetzen will, kann mit dem Plugin "dropShadow" einen ähnlichen Effekt erzielen, der aber ganz ohne Bilder auskommt: http://www.ihaslayout.com/experiments/menu-with-fadeeffect (nur im FF3 getestet)- natürlich nicht ganz so schick, aber sehr viel einfacher wartbar =)
lowpixel ¶
18. Februar 2009, 13:55 Uhr
Bemerke grade, dass es im IE nicht wirklich gut aussieht. Ich benutze 2.png's . Beim Wechsel zum Hoverbild sind um das neu erscheinende Bild während des Fadings schwarze unregelmässige Ränder!
Adrian ¶
29. Juni 2009, 11:38 Uhr
kann man dass ganze auch umdrehen, so dass sich der Glow-Effekt hinter dem button liegt ?? so wie hier http://labs.dragoninteractive.com/panel/demo/
dass wenn man auf den button klickt es außen rum am rand so leuchtet.
lowpixel ¶
29. Juni 2009, 13:46 Uhr
Ich denke da gibt es keinen Unterschied?! Als erstes Bild den Button ohne glow und als zweites den selbigen Button mit hellerer Schrift und glow am Rand.