Frage zum Wiki-Artikel „Dropdown-Menü“
Werner C.
- frage zum wiki
Hallo liebe Forumsleser
Ich bin neu hier in diesem Forum und versuche durch erstellen einer Homepage HTML, CSS, und JS zu lernen. Ich bin leider noch Anfänger.
Nun habe ich die Grundseiten erstellt und stehe vor einem Problem in der Navigationsleiste und ersuche um Unterstützung.
Ich habe eine horizontale Navigationsleisteund möchte keine aufklappbaren Dropdown Menüs. Wünschenswert wäre nach dem Anklicken eines Menübegriffes die Änderung der ggst. Menüzeile auf Begriffe (Menüpunkte als Untermenü anstelle des Hauptmenüs).
Ich habe trotz intensiver Suche keinen verständlichen Ansatz/Idee gefunden.
Quelltext kann über die HP http://wcanet.at eingesehen werden.
Ich hoffe in diesem Forum um Unterstützung.
Vielen herzlichen Dank.
Edit Rolf B: Artikel korrekt verlinkt, auf den sich die Frage bezieht und HP klickbar gemacht.
Hallo Werner,
dass die Dropdown-Menüs nicht funktionieren, liegt daran, dass <main> die "nach unten" hinaushängenden Boxen der Navigations <li> Elemente überlagert und deswegen der Hover-Effekt verloren geht. Das ist auch im Wiki-Beispiel unsauber. Vermutlich wurde da nicht mehr recht dran gearbeitet, weil eine Dropdown-Navigation nur mit CSS keine ordentliche Lösung erzeugt - wie auch im Wiki erwähnt wurde.
Wie auch immer - um die Navigation "hochzuheben", braucht sie einen z-index, und weil z-index nur für positionierte Elemente greift, braucht sie auch noch ein position:relative. Das wäre in deiner design.css in den Block ab Zeile 27 einzufügen:
nav {
...
position: relative;
z-index: 1;
}
Dazu kommt das Problem, dass Du den Navigations-Listenpunkten ein float:left verpasst hast. Das beißt sich mit dem Dropdown-Konzept, weil es die Listitems auf volle Höhe zwingt und das Verstecken mit Visibility nicht mehr funktioniert. Das float:left muss weg - das Nebeneinandersetzen der <li> erfolgt über das display:flex am ul Element.
Damit würde die Dropdown-Navigation besser funktionieren. Wenn Dir das generelle Design dieser Navigation nicht gefällt - über Details kann man sicher reden 😉
Das, was Du Dir wünschst, ist aber meiner Meinung auch für Maus-/Touch User schwer bedienbar. Wenn ich auf einen Menüpunkt mit Unterpunkten klicke, soll die Menüzeile ersetzt werden. Klicke ich auf einen Menüpunkt ohne Unterpunkte, wechsle ich gleich zur neuen Seite? Das ist nicht wirklich intuitiv.
Es fehlt für die Untermenüs dann auch eine "zurück" Funktion, mit der man die Hauptmenüleiste wieder erhält. Ich stelle mir das für jemanden, der die Seite über einen Screenreader ansurft, schwer bedienbar vor (die Bedienbarkeit ist bei reinen CSS Menüs ohnehin die größte Hürde).
Wie auch immer - das dürfte mit CSS nicht umsetzbar sein. Das sehe ich nur mit JavaScript lösbar. Und auch kein triviales Script.
Rolf
Hallo Werner,
du hast mir per Post geschrieben, dass Du auch eine JS Lösung nehmen würdest, sie dann auch gern verstehen willst.
Ich habe mal was gebastelt, das sicherlich noch Verbesserungspotenzial hat.
https://jsfiddle.net/Rolf_b/60ugek8h/
Das sind einfach mehrere Menüs, die jeweils in einem div eingekapselt sind. Das div deshalb, weil die Untermenüs einen vorangestellten Titel haben - der kann kein <li> sein und muss vor dem ul stehen. Eins der divs bekommt eine "aktiv" Klasse und wird dadurch sichtbar, die übrigen sind unsichtbar. Ich nehme an, dass hierfür irgendein aria-Attribut besser geeignet ist, aber bin nicht sicher, welches. ARIA ist eine HTML Erweiterung zur Bedienbarkeit (=Assistenztechniken).
In den Menüs sind Links. Einige davon haben ein data-menu Attribut, das sind Links, die Submenüs öffnen können. Das macht nicht das data-attribut, sondern das JavaScript - das data-Attribut dient nur zur Ablage von eigenen Infos an HTML Elementen. Normalerweise verwendet man für Aktionen, die auf der Seite bleiben, Buttons. Aber ich habe bewusst Links genommen, weil JavaScript auch deaktiviert sein kann. In dem Fall wird einfach auf eine Zwischenseite verlinkt, von der aus man weiter auswählen kann. Wenn JavaScript aktiv ist, erscheinen die Untermenüs. Das nennt man progressive Verbesserung (progressive enhancement).
Klicks auf die data-menu Links werden von JavaScript abgefangen. Das Script setzt einfach die "aktiv" Klasse auf das Menü, das unter data-menu angegeben ist. Über CSS wird dafür gesorgt, dass von den vorhandenen Menüs nur das zu sehen ist, das die aktiv-Klasse trägt.
<nav><div id="mainMenu" class="aktiv">
<ul>
<li><a href="/index.html">Startseite</a></li>
<li><a href="/wohnen.html" data-menu="wohnenMenu">Wohnen...</a></li>
<li><a href="/wetter.html" data-menu="wetterMenu">Wetter...</a></li>
<li><a href="/wissen.html" data-menu="wissenMenu">Wissen...</a></li>
<li><a href="/links.html">Links</a></li>
<li><a href="/weiteres.html" data-menu="weiteresMenu">Weiteres...</a></li>
</ul>
</div>
<div id="wohnenMenu">
<b>Wohnen:</b><ul>
<li><a href="/index.html" data-menu="mainMenu">zurück</a></li>
<li><a href="/essen.html">Essen</a></li>
<li><a href="/spielen.html">Spielen</a></li>
<li><a href="/schlafen.html">Schlafen</a></li>
</ul>
</div>
...
</nav>
// Suche das nav-Element und speichere es in einer Variablen
let navigation = document.querySelector("nav");
// Registriere auf dem nav Element einen Eventhandler für das click-
// Event. Button-Klicks werden nicht nur auf dem Button signalisiert,
// sondern auch auf der Eltern-Kette.
navigation.addEventListener("click", function(event) {
// Abfragen: Wurde ein Link geklickt oder was anderes?
if (event.target.tagName == "A") {
// Wenn Link: data-menu auslesen, das ist die ID des neuen Menüs
// Ist keine ID da, Eventhandler verlassen.
let menuId = event.target.dataset.menu;
if (!menuId) return;
// Dieses Menü heraussuchen
// Wenn es nicht existiert, Eventhandler verlassen
let newMenu = document.getElementById(menuId);
if (!newMenu) return;
// Dem bisher aktive Menü die "aktiv" Klasse wegnehmen...
navigation.querySelector(".aktiv").classList.remove("aktiv");
// und sie ans neue Menü anhängen.
newMenu.classList.add("aktiv");
// Verhindern, dass der Browser den Klick auf den Link verarbeitet.
event.preventDefault();
}
});
Ich kann Dir jetzt keinen JavaScript-Grundkurs machen, den findest Du im Self-Wiki. Dort sind auch die DOM Methoden wie querySelector, getElementById, addEventListener und preventDefault erklärt. Das ist eine ganze Menge an Wissen, die man da braucht, weil man zweierlei kennen muss: (a) die Sprache Javascript und (b) das Objektmodell des Browsers, auf dem man hantiert.
Rolf
Hallo Rolf
Vielen Dank, funktioniert genau so wie ich es mit vorgestellt habe. Danke auch für den Hinweis mit dem Home Link, daran hab ich erstmal nicht gedacht.
Ist auch sehr gut erklärt was da wie läuft. auch das JS, Super, vielen Dank dafür
Eine Kleinigkeit ist mir aufgefallen: Mit dem Home Link sollte die Indexseite im Main-Menü aufgerufen werden, die Menüleiste ändert sich zwar, aber der Seiteninhalt erscheint nicht sofort sondern man mauß auf der Indexseite den Link Startseite drücken. Sollte dies nicht mit dem Rücksprung/Aufruf der Indexseite passieren ?
LG Werner
Hallo Werner,
Mit dem Home Link sollte die Indexseite im Main-Menü aufgerufen werden
Mit dem "Home Link" meinst Du die "zurück" Links? Die referenzieren auf /index.html, ja, aber das ist der Fallback falls kein JavaScript ausgeführt wird. Der Normalfall sollte sein, aus einer Unter-Ebene in die Haupt-Ebene zurückzukehren. Dafür ist das gedacht. Du müsstest pro Seite, die das Menü enthält, überlegen, was der geeignete "zurück" Link ist. Es spricht auch nichts dagegen, in jeder Submenüebene einen Link zur Startseite unterzubringen - das führt nur zu einer Menge HTML-Doppelung.
Wie gesagt: das war ein Bastelergebnis. Damit hast Du jetzt ein Werkzeug geschenkt bekommen. Was genau du damit tust, ist deiner Kreativität überlassen.
Und Dir sollte klar sein, dass Du dieses Menü zwanzigmal duplizierst, wenn Du zwanzig Seiten hast. Wenn Du das nicht willst, bräuchtest Du eine serverseitige include-Technik, z.B. mit PHP.
Rolf