Dropdown Menü - Ein barrierefreies Typo3-Menü erstellen

Teil 1 - Ein barrierefreies Dropdownmenü für TYPO3 erstellen

Mit TYPO3 ist es sehr einfach in Windeseile ein barrierefreies Aufklapp-Menü zu erstellen. Mit ein paar CSS-Kniffen und ein bisschen Javascript läuft das Menü auf sämtlichen Browsern. Dropdown-Menüs haben gegenüber herkömmlicher Navigation den Vorteil, dass sie nicht erst mit mehreren Klicks zum Ziel führen und, dass sie für Suchmaschienen schneller lesbar sind.

Ich selbst habe dieses Script für mehrere Seiten verwendet (auch für mortox.de) und hatte damit bisher noch nie Probleme

Unser Ziel

Wir wollen ein einfaches Listenmenü, dass ungefähr so aussieht wenn es fertig ist:

Der Quellcode dafür lautet:

<ul class="menu">
  <li ><a href="#">Ebene1 Punkt1</a></li>
  <li onmouseover="show(this)" onmouseout="hide(this)" >
    <a href="#">Ebene1 Punkt2</a>
    <ul class="submenu" onmouseover="show(this)" onmouseout="hide(this)" >
      <li><a href="#">Ebene2 Punkt1</a></li>
      <li><a href="#">Ebene2 Punkt2</a></li>
      <li class="active"><a href="#">Ebene2 Punkt3</a></li>
    </ul>
  </li>
  <li><a href="#">Ebene1 Punkt3</a></li>
  <li><a href="#">Ebene1 Punkt4</a></li>
</ul>

Wie man sieht handelt es sich um eine einfache verschachtelte  Liste. Je nach Anzahl der Unterpunkte könnte man diese auch weiter verschachteln aber der Einfachkeit halber soll uns das vorerst genügen.

Der JavaScript Code onmouseover="show(this)" onmouseout="hide(this)" ist leider Pflicht, da man im Internet-Explorer 6 noch nicht die Chance hat über CSS auf das Pseudoelement li:hover und ul:hover zuzugreifen. Mit einer einfachen Funktion wenden wir daher die CSS-Klasse ".hover" per JavaScript auf diese Elemente an. Die beiden Funktionen show() und hide() sehen so aus:

<script type="text/javascript">
//<![CDATA[
function show(element){
element.className += "hover";
}
function hide(element){
element.className = element.className = "";
}
//]]>
</script>

Diesen Code am besten in den <head> der Seite einbinden.

Der CSS-Stil

Damit das Menü letztendlich auch noch funktioniert und so aussieht wie es soll, müssen natürlich noch einige CSS-Stile definiert werden. Für CSS-Listenmenüs gibt es zich Tutorials und Anleitungen im Internet, deswegen möchte ich da nicht weiter drauf eingehen. Ein paar wichtige und vielleicht verwirrende Zeilen hab ich dennoch kommentiert:

ul.menu, ul.menu ul {
list-style-type: none;
}

ul.menu a {
display: block;
padding: 3px 10px 3px 10px;
font-weight:normal;
}

ul.menu ul a {
padding: 0 10px;
}

ul.menu li {
padding:0;
margin:0;
background-image: none;
background-color: #FFF9E4;
float:left;
border:1px solid #26383D;
}

ul.menu ul {
margin-left:0;
padding: 0 0 5px 0;
position: absolute;
background-color: #26383D;
border:1px solid #FFF9E4;
display:none;
min-width:180px;
}

/* IE-Hack für die Breite */
*html ul.menu ul {
width:180px;
}

/* Dies sind die Klassenstile für das Untermenü wenn sich die Maus */
/* über der Liste befindet (.hover siehe JavaScript oben) */
ul.menu ul.hover, ul.menu li.hover ul, ul.menu li:hover ul {
display:block;
}

ul.menu ul li {
float:none;
background-color: transparent;
}

Das TypoScript fürs Dropdownmenü

Wenn wir alles so gemacht haben wie oben beschrieben, dürften wir bereits ein einfaches aber funktionales Aufklappmenü haben. Schön und gut - aber wie ersetzt man nun den Dummy-Inhalt mit der Seitenstruktur aus TYPO3?

Im Grunde ist das der einfachste Teil - weil sich TypoScript ganz einfach kopieren lässt :D Hier ist erstmal der Code, den ihr in euer Template einfügen müsst - die Erklärung kommt hinterher:

### Menü ###
lib.menu = HMENU
lib.menu {
### Erste Ebene ###
1 = TMENU
1 {
wrap = <ul class="menu">|</ul>
expAll = 1
NO.wrapItemAndSub = <li onmouseover="show(this)" onmouseout="hide(this)">|</li>

ACT < .NO
ACT = 1
ACT.ATagParams = class="active"
}

### Zweite Ebene ###
2 = TMENU
2 {
wrap = <ul onmouseover="show(this)" onmouseout="hide(this)">|</ul>
NO.allWrap = <li>|</li>
}
}

In meinem Fall wird das Menü an der Stelle lib.menu erstellt, weil ich meine Templates grundsätzlich mit TemplaVoila erstelle. Falls ihr lieber mit subparts arbeitet müsste an erster Stelle des Codes so etwas wie "subparts.MENU = HMENU" stehen.

Erklärungen:
Als erstes wird die erste Menüebene beschrieben (lib.menu.1). Die ganzen Menüpunkte werden mit "ul" und der Klasse "menu" umschlossen (wrap).

expAll wird auf 1 gesetzt, was bedeutet, dass folgende Unterpunkte auch dann angezeigt werden, wenn die Elternseite nicht aktiv ist... ansonsten würden unsere Dropdown-Listen ja leer sein.

Alle Normalen Seiten inklusive Unterseiten (NO.wrapItemAndSub) werden mit "li" und den onmouseover-Funktionen für den IE umschlossen.Aktive Seitenlinks sollen genau so dargestellt werden wie die normalen und werden daher nur kopiert (ACT < .NO). Lediglich der link bekommt eine zusätzliche CSS-Klasse "active" um ihn evtl. von den anderen hervorzuheben.

Für die zweite Menüebene geschieht im Grunde das gleiche, nur hab ich hier die Einstellungen für aktive Seitenlinks außer Acht gelassen - dies könnt ihr bei Bedarf aber einfach von oben kopieren. Außerdem wurde statt "wrapItemAndSub" ein "allWrap" verwendet, weil das Menü in unserem Beispiel ja keine dritte Menüebene besitzen soll.

Schlusswort

Das tolle an der Sache ist, dass sich der komplette TypoScript-Code und die JavaScript-Funktionen auf jede andere TYPO3-Seite übertragen lassen - lediglich der CSS-Stil muss dann noch angepasst werden.

Es ist ein Leichtes, dieses Tutorial auf eine Menüebene von 3 oder mehr auszuweiten. Dazu muss im TypoScript einfach eine weitere Menüebene (TMENU) angelegt werden und weitere CSS-Stile für die verschachtelten Listen definiert werden.

UPDATE

Da sich das Tutorial so großer Beliebtheit erfreut, gibt es jetzt auch noch ein Kurz-Tutorial für Dropdownmenüs mit 3 oder mehr Ebenen. Viel Spaß!

Design und Umsetzung Thomas Raithel (www.mortox.de)