Dropdown menu’s zijn handig. Zeker bij grote sites is het een ideale manier om met weinig klikken toch snel op de plek van bestemming uit te komen. Maar helaas worden deze menu’s maar al te vaak opgebouwd door middel van alleen JavaScript. Er wordt niet alleen JavaScript gebruikt voor de functionaliteit van het uitklappen, maar zelfs ook voor het opbouwen van de menu-items zelf. En dat is jammer, aangezien zoekmachines geen JavaScript uitvoeren en zo kun je dus de indexatie van je menu en dus waarschijnlijk zelfs hele delen van je website wel vergeten.
Gelukkig is daar een aantal jaren geleden een goede oplossing voor gevonden door de heren Patrick Griffiths en Dan Webb. Deze idee is uitgebracht onder de naam Suckerfish Dropdowns. Een jaar later kwam er een verbeterde versie uit onder de naam Son of Suckerfish en is nu een veel gebruikt menu. De kracht van het suckerfish menu is dat het een zo goed als puur CSS menu is. Er zit alleen een klein beetje JavaScript bij omdat Internet Explorer (t/m versie 6) de :hover pseudo-class niet volledig ondersteund.
Hieronder vind je de HTML code voor een dropdown menu met één niveau.
En hier zien we dan een mooi gestructureerde lijst. Hieronder nog even wat CSS toevoegen voor het uiterlijk.
padding: 0;
margin: 0;
list-style: none;
}
#nav a {
display: block;
width: 10em;
}
#nav li {
float: left;
width: 10em;
}
Zorg er echter wel voor dat je bij de #nav li een breedte opgeeft, anders zal het in Opera niet werken. Vergeet ook niet de (eventuele) content onder het menu te ‘clearen’ met clear: left;.
Nu moeten we er nog voor zorgen dat de lijsten die uitgeklapt moeten worden in eerste instantie verborgen zijn. Dit zou kunnen door middel van display: none;, maar omdat sommige screenreaders de elementen onzichtbaar maken is dit geen toegankelijke oplossing. Daarom maken we gebruik van de left eigenschap. In plaats van display: none; gebruiken we dan left: -999em; om de submenu’s te verbergen en later gebruiken we left: auto; om ze weer tevoorschijn te toveren. Voor dat terugtoveren gebruiken we dan onderstaande code.
position: absolute;
width: 10em;
left: -999em;
}
#nav li:hover ul {
left: auto;
}
Omdat Internet Explorer (t/m versie 6) helaas niet de :hover pseudo-class ondersteunt op andere elementen dan het a element, zijn we helaas verplicht tot en stukje JavaScript code.
var sfEls = document.getElementById(“nav”).getElementsByTagName(“LI”);
for (var i=0; i
this.className+=" sfhover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" sfhover\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
Dit script zorgt ervoor dat bij een mouseover op het desbetreffende li element de sfhover class wordt toegevoegd en bij de mouseout weer wordt weggehaald.
Nu moeten we alleen nog even het stuk CSS toevoegen om ook de sfhover class werkende te krijgen.
left: auto;
}
Zie daar, een werkende versie van een toegankelijk dropdown menu.
Noot: voor het gemak heb ik de CSS en het JavaScript even in de HTML file zelf geplaatst. Uiteraard is het netter om dit gescheiden te doen.
Het originele suckerfish artkikel werkte maar voor één niveau, maar met slechts wat kleine aanpassingen en logisch nadenkwerk kunnen we het makkelijk ombouwen naar een versie met meerdere niveaus. En, in tegenstelling tot de originele JavaScript code, is de ‘sfHover’ functie nu ook van toepassing op alle li elementen (ook de ‘descendants’ van de eerste li), zodat de meerdere niveaus in Internet Explorer ook mogelijk zijn.
Om maar weer met de HTML te beginnen hieronder het stuk code met daarin een extra niveau.
Er zijn nog een aantal andere zaken die moeten worden toegevoegd aan de eerste versie. Het tweede niveau (‘Echeneis’ enz.) moet namelijk niet naar onder worden uitgeklapt, maar opzij ten hoogte van de bijbehorende ‘moeder li‘ (‘Remoras’ in dit geval). Daarvoor hebben het volgende stuk CSS nodig.
margin: -1em 0 0 10em;
}
Omdat we namelijk de top van de absoluut gepositioneerde box niet kunnen definiëren , wordt deze onder de regel van de li die ‘gehovered’ wordt geplaatst. Daarom zetten we de margin-top op -1em zodat deze op dezelfde hoogte komt te staan. De dropdown menu’s komen nu wel hoger te staan, maar omdat de meeste ‘line-heights’ groter dan 1em staan ingesteld voegen we daarvoor het volgende stukje CSS aan de ul‘s toe.
padding: 0;
margin: 0;
list-style: none;
line-height: 1em;
}
Door het trapsgewijze (cascading) gedrag komt het tweede niveau ook automatisch tevoorschijn als je het eerste niveau uitklapt. Daarom moeten we ook het tweede niveau nog even expliciet verbergen.
left: -999em;
}
En om het tweede niveau tevoorschijn te halen draaien we bovenstaande regel om en voegen de volgende CSS toe:
left: auto;
}
En tadaa, een dropdown menu met twee niveaus.
Voor het geval dat je nu niveaus wilt toevoegen moet je er dus op letten dat je elke niveau expliciet verbergt en tevoorschijn haalt. Voor drie niveaus gebruik voeg je dan de volgende CSS toe:
left: -999em;
}
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li.sfhover ul, #nav li li.sfhover ul, #nav li li li.sfhover ul {
left: auto;
}
En mocht je er ooit vier nodig hebben geldt de volgende CSS code:
left: -999em;
}
#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li li li li:hover ul, #nav li.sfhover ul, #nav li li.sfhover ul, #nav li li li.sfhover ul, #nav li li li li.sfhover ul {
left: auto;
}
Waarschijnlijk heb je al de voorbeelden bekeken van dropdown menu’s van één niveau, twee niveaus en drie niveaus. Dit zijn mooie kale voorbeelden om de ‘techniek’ goed onder de knie te krijgen, maar je kan natuurlijk ook eens een kijkje nemen bij een wat mooier voorbeeld. Ook is het mogelijk om in plaats van een horizontaal menu een verticaal menu te maken.
Toevoeging: Roger wees me erop dat deze techniek niet goed werkt in IE7. De uitgeklapte dropdowns blijven namelijk nog wel eens hangen. Check de fix.