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>
Matrixnavi

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:

  1. Die <li> bekommen die Navigrafik als Hintergrundbild. Dieses wird jeweils so positioniert, dass es den normalen Zustand des Menüpunkts abbildet.
  2. Auch die <a> bekommen die Navigrafik als Hintergrundbild. Dieses wird jeweils so positioniert, dass es den Mouseover-Zustand des Menüpunkts abbildet.
  3. Beim Mouseover drehen wir einfach die Transparenz des jeweiligen <a> rauf und runter. So schaffen wir elegant einen einfachen Wechsel zwischen den Zuständen.
  4. 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.