Ein barrierefreies grafisches Menü mit TypoScript: GTMENU
Die Anforderungen an Internetseiten steigen. Viele Kunden fordern das Verwenden ihrer Hausschrift, weitestgehende Barrierefreiheit und Internetseiten, die auch ohne JavaScript funktionieren. Reine Grafik- oder Textmenüs erfüllen diese Anforderungen nicht. Einen Ausweg bieten Textmenüs, bei denen der verlinkte Text über CSS ausgeblendet und stattdessen eine Hintergrundgrafik angezeigt wird. Das bedient sowohl die Suchmaschine als auch den normalen Besucher der Website.
Der bei GMENUs über JavaScript gesteuerte MouseOver-Effekt soll über a:hover in CSS gesteuert werden. Dazu werden beide Zustände in eine Grafik geschrieben, die bei Mausberührung nach oben oder unten verschoben wird.
Basis für die Navigation ist eine Liste, die über <ul> und <li> abgebildet wird. Da die Navigation über TYPO3 dynamisch geschrieben wird, ist die Zeichenlänge der einzelnen Punkte und damit der generierten Hintergrundgrafiken vorher unbekannt. Die Elemente müssen sich also an die Breite der Navigationspunkte dynamisch anpassen können. Dazu wird über das „style“-Attribut die Breite individuell in jeden Link geschrieben.
<ul id="navi"> <li><a xhref="punkt-1.html" style="width:66px; background-image: url('/typo3temp/GB/ff8db8a838.gif');">Punkt 1</a></li> <li class="current"><a xhref="langer-navigationspunkt-2.html" style="width:212px; background-image: url('/typo3temp/GB/552f9f2db0.gif');">Langer Navigationspunkt 2</a></li> <li><a xhref="punkt-3.html" style="width:66px; background-image: url('/typo3temp/GB/bd319c7487.gif');">Punkt 3</a></li> </ul>
Listing 1
Die Formatierung der Navigation übernimmt eine knappe CSS-Datei. Diese hat zwei Hauptaufgaben:
- Ausblenden des Texts durch Verschieben außerhalb des sichtbaren Bereichs (text-indent:999em)
- Verschieben der Hintergrundgrafik bei Mausberührung, sodass der vorher verdeckte Teil der Grafik auftaucht (background-position:0px -30px)
ul#navi {list-style: none;} ul#navi li {float: left;} ul#navi li a {background-repeat:no-repeat; display:block; overflow:hidden;text-indent:999em; white-space:nowrap; height:30px;} ul#navi li a:hover, ul#navi li.current a,ul#navi li.over a {background-position:0px -30px;}
Listing 2
Umsetzung des Menüs per TypoScript
Zunächst wird ein reguläres TMENU [1] in Form einer Liste erstellt, aber die Verlinkung dieser Elemente ausgeschaltet, da der Link später noch bearbeitet wird.
lib.gtmenu = HMENU lib.gtmenu { 1 = TMENU 1 { wrap = <ul id="navi">|</ul> NO.doNotLinkIt = 1 NO.wrapItemAndSub = <li>|</li> [...]
Listing 3
Anschließend wird der NO-Zustand als eigenes Content Object Array (COA) definiert, um den Link nach eigenen Wünschen zusammenstellen zu können.
[...] NO.stdWrap.cObject = COA NO.stdWrap.cObject { 10 = TEXT 10 { field = title typolink { parameter.field = uid [...]
Listing 4
Über den Style-Parameter des Links wird die Hintergrundgrafik hinterlegt. Um einem Link weitere Eigenschaften mitzugeben, bietet TypoScript die Eigenschaft „AtagParams“ an, die oftmals mit CSS-Anweisungen befüllt wird. Hier muss jedoch eine Grafik auftauchen. Dafür wird auch AtagParams als COA definiert, indem über IMG_RESOURCE die Hintergrundgrafik generiert wird. Diese wird wie beim GMENU über den GIFBUILDER erstellt [2]. Der hover-Zustand wird in die gleiche Grafik weiter unten eingebaut.
[...] ### AtagParams als COA definieren, um die Grafik rendern zu können ### ATagParams.cObject = COA ATagParams.cObject { ### Image-Resource nach unseren Wünschen generieren ### 10 = IMG_RESOURCE 10.file = GIFBUILDER 10.file { XY = [10.w]+[20.w]+10,70 transparentColor = #ffffff 10 = TEXT 10 { text.field = subtitle//title fontSize = 14 fontFile=fileadmin/fonts/verdana.ttf offset = 5,20 fontColor = #787879 } ### Roten Hintergrund für den Rollover definieren ### 20 = BOX 20.dimensions = 0,30,[10.w]+[20.w]+10,30 20.color = #e53827 ### Text für den Rollover kopieren, nach unten verschieben und einfärben ### 30 = TEXT 30 < .10 30 { offset = 5,50 fontColor = #ffffff } } [...]
Listing 5
Eine besondere Schwierigkeit beim Menü stellt die unterschiedliche Breite der Navigationspunkte dar. Um nicht alle Elemente gleich breit zu machen und damit unschöne Lücken zu erhalten, muss ermittelt werden, wie breit die jeweilige Grafik geworden ist. Seit Version 4.1 steht in TYPO3 das Array TSFE:lastimageResourceInfo bereit [3], das verschiedene Eigenschaften der zuletzt über den GIFBUILDER generierten Grafik zurückgibt. Hier wird auf die Breite zugegriffen und mittels eines dataWraps zusammen mit der von IMG_RESOURCE zurückgegebenen URL in den Link geschrieben.
[...] 10.stdWrap.dataWrap = style="width:{TSFE:lastImgResourceInfo|0}px; background-image: url('/|');" } } } } } }
Listing 6
Damit ist die Navigation umgesetzt [4]. Natürlich bieten sich durch die Anpassung der CSS-Datei noch weitere Freiheiten in der Gestaltung des Menüs. So kann beispielsweise in TypoScript noch ein CUR- oder ACT-Zustand für aktive Navigationselemente definiert und wie im oberen Beispiel (Listing 1) zu sehen über class="current" in CSS mit entsprechenden Eigenschaften formatiert werden. Denkbar sind daher auch noch weitere Zustände, die alle in die gleiche Grafik über den GIFBUILDER geschrieben werden, die dann per CSS-Klasse an die entsprechende Position verschoben wird.
Fazit
Durch die konsequente Verwendung des hier vorgestellten Menüs [5] wird das altgediente GMENU überflüssig. Statt dessen erhält man eine Navigation, die alle Vorteile der Barrierefreiheit eines TMENUs und der grafischen Freiheit des GMENUs in sich vereinigt, ohne die bekannten Nachteile in Kauf nehmen zu müssen.
Ein weiterer Vorteil dieser Herangehensweise ist die kürzere Ladezeit der Grafiken, da keine eigene Datei für den Rollover-Zustand geladen werden muss. Somit entfallen auch unschöne Verzögerungseffekte beim Austausch der Datei über JavaScript.
Tolles Skript, Jochen. Schön, dass die Accessibility endlich auch in der T3N immer stärker in den Fokus rückt.
Ich versuche gerade ähnliches für einen Kunden um zu setzen und habe noch ein Problem: Die zweite Ebene der Menüpunkte soll vertikal unter den Buttons der ersten erscheinen und diese sollen jeweils die gleiche Breite haben, wie der Menüpunkt auf erster Ebene. Die Interner Explorer stellen das UL-Element aber allesamt mit falscher Breite dar.
Ich würde deshalb gerne die Breite des Bildes in die Zweite Ebene weiterreichen, also ungefähr
2.wrap = |
Die {TSFE:lastImgResourceInfo|0}-Angabe wird unten aber nicht mehr geparst und nicht durch die Breite des Bildes ersetzt.
Ich habe leider von TS noch nicht wirklich viel Ahnung, kannst du mir auf die Sprünge helfen?
Ach. Mist, Tags werden geschluckt, so sollte das aussehen:
2.wrap = <ul style=“width:{TSFE:lastImgResourceInfo|0}px; background-image: url(‚/|‘);“>|</ul>
Danke für das gute Script! Einen kleinen Bug habe ich entdeckt (welcher sporadisch Menüpunkte nicht anzeigt wenn man keinen „Rollover“ Hintergrund verwendet): Das „+[20.w]“ wird nicht benötigt.
Schade, super Umsetzung des Menüs, aber irgendwas mache ich falsch.
Zwar habe ich jetzt die verlinkten Grafiken, aber die Textlinks sind weiterhin darüber sichtbar.
Und meine bereits erstellen Überschriften Grafiken (funktionierte ganz ähnlich) gehen nicht mehr. Da wird nicht einmal mehr eine Grafik erstellt. Irgendwie hebt sich das durch das Menü auf. :-(
Für Anfänger nicht brauchbar. Was soll das lib. vor gtmenu????????????
Muss da nicht ein Marker sein? Ich kann das so nicht nachbauen.
Es wird kein a-Tag angezeigt, auch wenn ich einen Marker „gtmenu“ einführe.