Tab-Menü ohne JavaScript
Was ist ein Tab-Menü?
Viele kennen sicher die sog. Drop-Down-Menüs. Das sind die Menüs, die aus mehreren Haupt-Links bestehen, unter denen sich beim Überfahren mit der Maus ein Sub-Menü ausklappt. Diese Menüs sind nicht bei allen Leuten beliebt, besonders, da sie oft nur mit JavaScript laufen, obwohl es technisch auch ohne geht. JavaScript kommt dort meistens nur zum Einsatz, um das ganze schöner wirken zu lassen.
Bei den Drop-Down-Menüs gibt es also ein Haupt-Menü, welches die Kategorien oder Haupt-Links enthält und unter jedem dieser Links jeweils ein Sub-Menü, welches sich nur zeigt, wenn sich die Maus darüber befindet. Die Links in diesem Sub-Menüs stehen untereinander.
Beim Tab-Menü gibt es ebenfalls Haupt-Links und Submenüs. In diesen werden die Links aber nebeneinander angeordnet, sodass das Menü in einer Art Tabs aufgebaut ist. Um dies nur mit HTML und CSS zu erreichen bedarf es einiger Erfahrung. Deshalb möchte ich nun erklären, wie ich zu meinem Lösungsansatz kam.
Die Lösungsansätze
Zuerst einmal sollte ich wohl noch genau zeigen, was ich eigentlich meine:
![]()
Das Bild rechts zeigt mein Ziel bzw. Endergebnis. Oben stehen die Kategorien bzw. Haupt-Links, unten darunter jeweils die Submenüs in Form von Tabs. Hier nochmal eine Live-Demo.
Wie nun funktioniert der Lösungsansatz? Zuerst benötigt man ein div für das komplette Menü inklusive Sub-Menüs. Dieses wird dann später im Layout beliebig ausgerichtet. Darin befinden sich zuerst alle Haupt-Links. Diese sind ganz normale a-Elemente, denen allerdings kein href-Attribut zugewiesen wird. Natürlich könnte man sie gleichzeitig auch als ganz normale Links verwenden, dies macht aber nur Sinn, wenn man auch Übersichtsseiten für die jeweiligen Kategorien anzubieten hat. Schließlich sollen die Links nicht ins Nichts laufen. Unter unseren Haupt-Links werden nun die einzelnen Sub-Navis platziert. Sie selbst sind immer noch nichts besonderes. Sie enthalten lediglich die jeweiligen Sub-Links.
Spannend wird es nun mit CSS. Das Prinzip des Tab-Menüs beruht nämlich darauf, dass jeweils nur die benötigten Sub-Menüs überhaupt angezeigt werden. Im Normalfall sind sie ausgeblendet. Erst, wenn einer der Haupt-Links mit der Maus überfahren wird (hover), erscheint das jeweilige Sub-Menü.
Darin besteht auch der Knackpunkt: Wie blenden wir div-Elemente aus? Zum einen könnte man sie durch relative Positionierung einfach aus dem Bildschirm schieben. Dann hat man aber das Problem, dass sie immer wieder an ihren alten Platz zurückkehren, da sie normalerweise ja untereinander bzw. nebeneinander stehen. Für diese Methode müsste ich genau wissen, wo ein Sub-Menü stehen soll und das ist bei relativer Positionierung leider alles andere als einfach.
Eine andere Möglichkeit ist, die div-Elemente einfach unsichtbar zu machen. Dazu verwendet man in CSS das Attribut visibility. Dummerweise werden die div-Elemente dann wirklich nur unsichtbar. Sie nehmen aber dennoch Platz ein.
Tatsache ist, dass wir ein div-Element nicht wirklich verschwinden lassen können. Glücklicherweise reicht es uns aber auch, es einfach nur so klein zu machen, dass es uns nicht mehr stört. Wir machen die Sub-Menüs also einfach so klein, dass man sie nicht sieht. Erst, wenn sie benötigt werden, dürfen sie sich ausbreiten.
Zum Aufbau des Menüs in HTML
Erst benötigen wir natürlich ein valides HTML-Grundgerüst. Dieses sollte jeder selbst erstellen können. Wenn nicht, gibt es dafür ja meine Tutorial-Reihe. In den folgenden Ausschnitten, werde ich das Grundgerüst weglassen. Man müsste es sich also dazu denken.
Zuerst wollen wir ein div einrichten, welches das ganze Menü einrahmt, damit es uns nicht auseinander “läuft”:
1 2 3 | <div id="menu"> </div> |
Innerhalb dieses div-Elements richten wir nun unsere Haupt-Links für die einzelnen Kategorien ein. Sie sollten später natürlich eine bessere Beschriftung erhalten als hier im Beispiel
1 2 3 4 5 | <a id="menu_link">Link 1</a> <a id="menu_link2">Link 2</a> <a id="menu_link3">Link 3</a> <a id="menu_link4">Link 4</a> <a id="menu_link5">Link 5</a><br /> |
Theoretisch lassen sich so beliebig viele Links einrichten. Man muss lediglich beachten, dass jeder eine eigene ID hat, das Menü irgendwann nicht mehr genug Platz findet und auf den letzten dieser Links ( und nur auf den letzten ) ein br-Tag folgt. Dieser ist dafür zuständig, dass die Sub-Menüs eine Reihe tiefer erscheinen.
Kommen wir nun zu den Sub-Menüs. Diese werden jeweils in div-Elemente eingefasst. Sie sind jeweils mit einer eigenen ID zu versehen, damit in CSS später vom richtigen Haupt-Link ein Bezug zum richtigen Sub-Menü hergestellt werden kann. Die einzelnen Links in den jeweiligen Sub-Menüs erhalten alle die Klasse submenu_link, damit sie später schöner gestaltet werden können.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <div id="menu_content"> <a href="" class="submenu_link">Sub-Link 1.1</a> <a href="" class="submenu_link">Sub-Link 1.2</a> <a href="" class="submenu_link">Sub-Link 1.3</a> </div> <div id="menu_content2"> <a href="" class="submenu_link">Sub-Link 2.1</a> <a href="" class="submenu_link">Sub-Link 2.2</a> <a href="" class="submenu_link">Sub-Link 2.3</a> </div> <div id="menu_content3"> <a href="" class="submenu_link">Sub-Link 3.1</a> <a href="" class="submenu_link">Sub-Link 3.2</a> <a href="" class="submenu_link">Sub-Link 3.3</a> </div> <div id="menu_content4"> <a href="" class="submenu_link">Sub-Link 4.1</a> <a href="" class="submenu_link">Sub-Link 4.2</a> <a href="" class="submenu_link">Sub-Link 4.3</a> </div> <div id="menu_content5"> <a href="" class="submenu_link">Sub-Link 5.1</a> <a href="" class="submenu_link">Sub-Link 5.2</a> <a href="" class="submenu_link">Sub-Link 5.3</a> </div> |
Diesen Links müsste natürlich später ebenfalls ein sinnvolles Ziel und eine sinnvolle Beschriftung verpasst werden.
Der ganze HTML-Teil sieht nun wie folgt aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <div id="menu"> <a id="menu_link">Link 1</a> <a id="menu_link2">Link 2</a> <a id="menu_link3">Link 3</a> <a id="menu_link4">Link 4</a> <a id="menu_link5">Link 5</a><br /> <div id="menu_content"> <a href="" class="submenu_link">Sub-Link 1.1</a> <a href="" class="submenu_link">Sub-Link 1.2</a> <a href="" class="submenu_link">Sub-Link 1.3</a> </div> <div id="menu_content2"> <a href="" class="submenu_link">Sub-Link 2.1</a> <a href="" class="submenu_link">Sub-Link 2.2</a> <a href="" class="submenu_link">Sub-Link 2.3</a> </div> <div id="menu_content3"> <a href="" class="submenu_link">Sub-Link 3.1</a> <a href="" class="submenu_link">Sub-Link 3.2</a> <a href="" class="submenu_link">Sub-Link 3.3</a> </div> <div id="menu_content4"> <a href="" class="submenu_link">Sub-Link 4.1</a> <a href="" class="submenu_link">Sub-Link 4.2</a> <a href="" class="submenu_link">Sub-Link 4.3</a> </div> <div id="menu_content5"> <a href="" class="submenu_link">Sub-Link 5.1</a> <a href="" class="submenu_link">Sub-Link 5.2</a> <a href="" class="submenu_link">Sub-Link 5.3</a> </div> </div> |
Wer den obigen Code von der Idee her nicht nachvollziehen kann, der sollte sich vielleicht die Live-Demo ansehen. Wer den Code selbst nicht versteht, der benötigt wohl noch einige grundlegende Fähigkeiten in Sachen HTML.
Zum Aufbau in CSS
Nun wird es komplizierter. Vorweg sollte ich einige Sachverhalte erklären. Zum einen ist da das Attribut visibility (Sichtbarkeit). Dieses kann den Wert “visible” erhalten, wenn das jeweilige Element angezeigt werden soll, oder “hidden”, wenn es ausgeblendet werden soll. Allerdings wird das Element dann wie erwähnt nur unsichtbar. Es benötigt weiterhin seinen Platz.
Desweiteren benötigt man den sog. Schwesternselektor. Bei einer normalen CSS-Definition passiert beispielsweise folgendes:
1 2 3 | small{ [...] } |
Die Definition würde nun für alle small-Elemente gelten. Wenn man aber erreichen möchte, dass die Definition für ein bestimmtes Element gültig ist, dass auf ein bestimmtes anderes Element folgt, benötigt man den Schwesternselektor. Dieser besteht aus einer Tilde (~):
1 2 3 | div ~ small { [...] } |
Diese Definition würde nun für alle small-Elemente gelten, die nach einem div-Element stehen. Dabei ist zu beachten, dass das jeweilige div-Element und das jeweilige small-Element auf derselben Ebene stehen. Das heißt, das small-Element müsste sich in demselben Tag befinden wie das div-Element selbst. Allerdings muss das small-Element nicht direkt auf ein div-Element folgen. Es dürfen andere Elemente dazwischen stehen, solange sie sich dennoch auf derselben Ebene befinden.
Vorbereitung der Submenüs
Kümmern wir uns nun erstmal wieder um die Submenüs und deren Standard-Eigenschaften. Die Submenüs sollen standardmäßig so klein sein, dass sie nicht stören. Dazu setzen wir ihre Breite (width) auf 0 px. Außerdem ist es wichtig, dass die Sub-Menüs ‘floaten’, damit sie nebeneinander stehen und sich immer schön links anordnen.
Damit wir von den Submenüs auch wirklich nichts sehen, werden sie sicherheitshalber noch mit dem visibility-Attribut ausgeblendet:
1 2 3 4 5 | #menu_content, #menu_content2, #menu_content3, #menu_content4, #menu_content5{ visibility : hidden; width : 0px; float : left; } |
Wie man oben sieht, kann ich die Definition für alle Submenüs gleichzeitig abwickeln, indem ich die einzelnen IDs (mit führender Raute!) jeweils durch Kommata trenne. Die Definition ist jetzt also für alle Submenüs gültig.
Kümmern wir uns als nächstes um das größte Problem: Wie lassen wir unsere Submenüs erscheinen? Gut verborgen sind sie ja schonmal. Normalerweise lassen sich Elemente ja verändern, wenn die Maus darüber fährt bzw. “schwebt”. In diesem Fall sollen die Submenüs aber erscheinen, wenn die Maus über einem anderen Element schwebt. Dabei hilft uns der Schwesternselektor:
1 2 3 | #menu_link:hover ~ #menu_content{ } |
Diese Definition ist gültig für alle Elemente, welche die ID “menu_content” tragen und irgendwann auf derselben Ebene auf ein Element folgen, welches die ID “menu_link” besitzt. Außerdem verknüpfen wir diese Definition noch mit einer Pseudoklasse: “:hover”. Wenn nun also die Maus über dem Element mit der ID “menu_link” schwebt, dann wirkt sich die Definition auf das Element mit der ID “menu_content” aus. Beide Elemente haben wir bereits in HTML eingebaut. #menu_link ist der erste Haupt-Link, #menu_content das erste Submenü.
Nun, da wir diesen wichtigen Schritt geschafft haben, sollten wir natürlich noch die Definition füllen, sodass das jeweilige Submenü auch erscheint. Dazu machen wir im Prinzip genau das Gegenteil von dem, was wir in der Standard-Definition für die Submenüs getan haben:
1 2 3 4 | #menu_link:hover ~ #menu_content{ visibility : visible; width : auto; } |
Nun erscheint das Submenü bereits, wenn die Maus sich auch über dem entsprechenden Haupt-Link befindet. Allerdings muss diese Definition nun noch für alle anderen Submenüs angelegt werden. Leider können wir sie diesmal nicht zusammenfassen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #menu_link:hover ~ #menu_content{ visibility : visible; width : auto; } #menu_link2:hover ~ #menu_content2{ visibility : visible; width : auto; } #menu_link3:hover ~ #menu_content3{ visibility : visible; width : auto; } #menu_link4:hover ~ #menu_content4{ visibility : visible; width : auto; } #menu_link5:hover ~ #menu_content5{ visibility : visible; width : auto; } |
Damit haben wir das Gröbste hinter uns. Obwohl wir noch vor ein paar anderen Problemen stehen: Wenn wir unsere Maus nämlich nun vom Haupt-Link herunter bewegen, verschwindet das Submenü wieder. Ein recht unpraktisches Verhalten. Das wollen wir ihm abgewöhnen, indem wir hierfür eine weitere CSS-Definition anlegen, welche die Pseudoklasse “:hover” auf die Submenüs selbst anwendet:
1 2 3 4 | #menu_content:hover, #menu_content2:hover, #menu_content3:hover, #menu_content4:hover, #menu_content5:hover{ visibility : visible; width : auto; } |
Diese Definition tut eigentlich nichts anderes als die letzte, welche das Submenü zum Vorschein bringt. Aus diesem Grund können wir diese beiden auch zusammenfassen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #menu_link:hover ~ #menu_content, #menu_content:hover{ visibility : visible; width : auto; } #menu_link2:hover ~ #menu_content2, #menu_content2:hover{ visibility : visible; width : auto; } #menu_link3:hover ~ #menu_content3, #menu_content3:hover{ visibility : visible; width : auto; } #menu_link4:hover ~ #menu_content4, #menu_content4:hover{ visibility : visible; width : auto; } #menu_link5:hover ~ #menu_content5, #menu_content5:hover{ visibility : visible; width : auto; } |
Übrigens: Die fünf Definitionen oben können wir deshalb nicht zu einer zusammenfassen, weil sie sich ja immer auf die einzelnen Submenüs beziehen. Würde man sie zusammenfassen, könnte jeder Link alle Submenüs zum Vorschein bringen, was eine nicht sehr nützliche Funktion wäre.
Fassen wir also den gesamten CSS-Teil nochmal zusammen, soweit wir ihn haben:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #menu_content, #menu_content2, #menu_content3, #menu_content4, #menu_content5{ visibility : hidden; width : 0px; float : left; } #menu_link:hover ~ #menu_content, #menu_content:hover{ visibility : visible; width : auto; } #menu_link2:hover ~ #menu_content2, #menu_content2:hover{ visibility : visible; width : auto; } #menu_link3:hover ~ #menu_content3, #menu_content3:hover{ visibility : visible; width : auto; } #menu_link4:hover ~ #menu_content4, #menu_content4:hover{ visibility : visible; width : auto; } #menu_link5:hover ~ #menu_content5, #menu_content5:hover{ visibility : visible; width : auto; } |
Das Tab-Menü ist in diesem Zustand bereits voll funktionstüchtig. Der Quellcode hierzu hält sich sogar sehr gering. Wir haben also mit wenig Aufwand ein tadelloses Tab-Menü erstellt. Allerdings ist es noch nicht besonders schick.
Das Design
Für diejenigen, die sich das Designen nicht wirklich zutrauen oder einfach keine Idee haben, wie sie es machen könnten, zeige ich nun, wie es aussehen könnte:
Das Menü selbst
Das Menü, welches alles beisammen hält, könnte noch ein bisschen Styling vertragen. Dazu werden wir ihm eine Hintergrund-Farbe und einen angerundeten Rahmen verpassen und es zentrieren. Außerdem definieren wir einen Abstand nach Innen und schließen den Block-Floating-Context durch das overflow-Attribut:
1 2 3 4 5 6 7 8 9 10 11 12 | #menu{ border : 1px #CCC solid; background-color : #CCC; width : 960px; margin : auto; height : 65px; overflow : hidden; -webkit-border-radius : 10px; -moz-border-radius : 10px; border-radius : 10px; padding : 25px 20px; } |
Von diesen Attributen sollten die meisten bekannt sein. Lediglich folgende drei Zeilen sind womöglich ein wenig befremdlich:
1 2 3 | -webkit-border-radius : 10px; -moz-border-radius : 10px; border-radius : 10px; |
Sie bewirken jedoch nichts anderes, als dass die Ecken des Elements (bzw. der Rahmen) um 10px abgerundet werden. Das ist eigentlich total überflüssig, sieht aber besser aus.
Es handelt sich hier um ein Feature von CSS3. Dieses ist noch nicht ganz fertig, was dazu führt, dass wir ein wenig tricksen müssen, um es bei allen gängigen und aktuellen Browsern ans laufen zu bringen. Wie es genau funktioniert braucht ja eigentlich nicht weiter zu interessieren. Wichtig ist nur, dass man weiß, was diese Zeilen da überhaupt tun!
Die Haupt-Links
Um nun ein Tab-Ähnliches Feeling zu erzielen, müssen wir die Haupt-Links noch ein wenig bearbeiten. Dazu geben wir einmal Definitionen für den Normalzustand und einmal eine für die darüber schwebende Maus an:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #menu_link, #menu_link2, #menu_link3, #menu_link4, #menu_link5{ border : 1px transparent solid; background-color : transparent; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 5px; color : #333; cursor : pointer; } #menu_link:hover, #menu_link2:hover, #menu_link3:hover, #menu_link4:hover, #menu_link5:hover{ border : 1px #333 solid; background-color : #333; color : #fff; } |
Diese Definitionen sollte eigentlich nachvollziehbar sein, dennoch gehe ich sie kurz durch: Im Normalzustand hat jeder Haupt-Link einen unsichtbaren Rahmen. Dieser ist abgerundet und wird erst sichtbar, wenn sich die Maus darüber befindet. Ist er sichtbar, hat er dieselbe Farbe wie der Hintergrund des Links. Dieser wird nämlich dunkelgrau hinterlegt. Außerdem besitzen die Links Abstand nach Innen und wechseln zur besseren Lesbarkeit die Farbe, sobald die Maus darüber schwebt. Diese wird über den Links durch das Cursor-Attribut auch zu einer Hand.
Submenüs
Die Submenüs selber erhalten ein Design wie die Haupt-Links. Nur nehmen sie halt mehr Platz ein und stehen so nah am jeweiligen Haupt-Link, dass sie sich mit diesem überlappen wodurch dann endgültig das Aussehen eines Tab-Menüs entsteht:
1 2 3 4 5 6 7 8 9 10 11 12 | #menu_content, #menu_content2, #menu_content3, #menu_content4, #menu_content5{ visibility : hidden; width : 0px; border : 1px #333 solid; background-color : #333; color : #fff; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 15px; float : left; } |
Submenü-Links
Abschließend fehlt noch die Gestaltung der Links innerhalb der Submenüs. Wir hatten diesen ja im HTML-Teil eine Klasse zugewiesen, über welche wir sie nun ansprechen:
1 2 3 4 5 6 7 8 9 10 11 12 13 | a.submenu_link{ color : #fff; border : 1px transparent solid; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 5px; text-decoration : none; } a.submenu_link:hover{ border : 1px #fff solid; } |
Zusammenfassend sieht unser CSS-Teil nun so aus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #menu{ border : 1px #CCC solid; background-color : #CCC; width : 960px; margin : auto; height : 65px; overflow : hidden; -webkit-border-radius : 10px; -moz-border-radius : 10px; border-radius : 10px; padding : 25px 20px; } #menu_link, #menu_link2, #menu_link3, #menu_link4, #menu_link5{ border : 1px transparent solid; background-color : transparent; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 5px; color : #333; cursor : pointer; } #menu_link:hover, #menu_link2:hover, #menu_link3:hover, #menu_link4:hover, menu_link5:hover{ border : 1px #333 solid; background-color : #333; color : #fff; } #menu_link:hover ~ #menu_content, #menu_content:hover{ visibility : visible; width : auto; } #menu_link2:hover ~ #menu_content2, #menu_content2:hover{ visibility : visible; width : auto; } #menu_link3:hover ~ #menu_content3, #menu_content3:hover{ visibility : visible; width : auto; } #menu_link4:hover ~ #menu_content4, #menu_content4:hover{ visibility : visible; width : auto; } #menu_link5:hover ~ #menu_content5, #menu_content5:hover{ visibility : visible; width : auto; } #menu_content, #menu_content2, #menu_content3, #menu_content4, #menu_content5{ visibility : hidden; width : 0px; border : 1px #333 solid; background-color : #333; color : #fff; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 15px; float : left; } a.submenu_link{ color : #fff; border : 1px transparent solid; -webkit-border-radius : 4px; -moz-border-radius : 4px; border-radius : 4px; padding : 5px; text-decoration : none; } a.submenu_link:hover{ border : 1px #fff solid; } |
Fazit
Das normale Drop-Down-Menü ist mit HTML und CSS nicht besonders schwer zu erzeugen, wenn man das Prinzip verstanden hat. Dieses Tab-Menü hingegen hätte ich wegen verschiedenster Probleme für technisch unmöglich gehalten. Zumindest ohne JavaScript. Tatsächlich ist es mir aber nach ein wenig Nachdenken gelungen die Probleme zu beseitigen. Recht schick ist es außerdem. Ich werde es zwar selbst nicht brauchen, aber andere Leute vielleicht. Diese können sich dann darüber freuen. Und wenn diese sich darüber freuen, dann sollen sie es mich bitte wissen lassen
Hier entlang zum Endergebnis als Live-Demo!
