Zur Navigation

Zwei Navis (desktop-first), die mobile per Toggle-Klickbutton aus-/einklappen sollen

1 Martin

Hallo,
ich bin dabei, meine alten WP-Sites auf reines HTML und CSS umzustellen, mit einem dreispaltigen Grid. Ich nutze Visual Studio Code.

Desktop-first ist soweit alles erledigt, HTML und CSS. Im letzten Schritt geht es jetzt darum, die Site responsiv zu machen. Problem sind da die beiden Navs, die mit JavaScript funktionieren sollen, ich kann das aber nicht und außer für die Navs brauche ich es auch nicht.

Die Seiten haben eine horizontale und eine vertikale Nav (ohne Dropdown-Untermenü), die für mobile-Geräte (media query) als zwei aus/einklappbare HTML-Buttons erscheinen sollen.

Das Aus/Einklappen soll mit einem Klickevent durch Javascript und aria-expanded passieren.

Leider habe ich von JS keine Ahnung. Zwei Beispiele im Web kommen meiner Nav zwar nahe (HTML-Button, aria-expanded, desktop-first), aber die Codes unterscheiden sich.


Der HTML-Code der ersten Nav und das nötige CSS sieht wie folgt aus und sollte soweit passen (die zweite Nav hat den "gleichen" HTML-Code, nur andere Klassennamen). Die Anpassung der Stylings mache ich dann hinterher.

Kann man das hier im Forum besprechen oder ist das zu kompliziert?

<nav class="headnav" aria-label="label1">
  <button class="headnav-button" aria-expanded="false" type="button">Menü 1<span class="button-pfeil">&#x25bc;</span></button>
  <ul class="headnav-haupt-ul">
    <li><a href="url1">Linktext1</a></li>
    <li><a href="url2">Linktext2</a></li>
    <li><a href="url3">Linktext3</a></li>
    <li><a href="url4">Linktext2</a></li>
    <li><a href="url5">Linktext5</a></li>
    <li><a href="url6">Linktext6</a></li>
  </ul>
</nav>


CSS :

button.headnav-button {
    display: none; 
    padding-top: 5px;
    padding-bottom: 5px;
    padding-right: 15px;
    padding-left: 15px;
    font-family: Arial;
    font-size: 1rem;
    background-color:#fffbf1; /*  */
    order: 2px solid #000000; /*  */
}

button.headnav-button > span.button-pfeil {
    margin-left: 10px;
}

/* responsiver Code, media query */
@media screen and (max-width: 600px) {
div.grid-container { 
  display: grid;
  max-width: 600px; 
  grid-template-columns: 1fr 1fr; 
  grid-template-rows: auto auto; 
  grid-template-areas: 
    "header header"
    "headnav sidenav"
    "main main"
    "aside aside"
    "footer footer"; 
  background-color: #ffffff; 
  margin-left: auto; 
  margin-right: auto; 
  padding: 9px; 
  border: 1px solid black; 
  margin-top: 3px; 
  margin-bottom: 3px; 
  border-radius: 6px;
}

/* responsiver Code, Button eingeblendet */
button.headnav-button, button.sidenav-button {
  display: block;
}

/* responsiver Code, ul ausgeblendet */
ul.headnav-haupt-ul, ul.sidenav-ul {
  display: none;
}

13.09.2025 11:37

2 Jörg Kruse

Ein Beispiel war vermutlich das hier:

https://jamesevers.co.uk/articles/creating-an-accessible-navigation-menu-and-toggle-with-vanilla-javascript

Du kannst das Script für deine Navigation verwenden, indem du die Selektoren an dein HTML anpasst:

const navToggle = document.querySelector('.headnav-button');
const navList = document.querySelector('.headnav-haupt-ul');
const navLinks = document.querySelectorAll('.headnav-haupt-ul li a');

13.09.2025 15:19

1 Forenmitglied fand diesen Beitrag gut

3 Martin

Das wäre ja super, wenn es so einfach wäre. Das Beispiel ist recht überschaubar.

Über dein Beispiel bin ich auch gestolpert, habe es aber nicht weiter verfolgt, wegen folgendem Satz:
"In essence it uses a hidden attribute on the nav element to determine its visible state, and that is controlled via a click event on a button."

Das hat mich irritiert. Der "übliche" und korrekte Weg, den ich auch so gewählt habe, ist wohl der, dass
- der Button desktop-first ausgeblendet wird,
- der Button mobile eingeblendet wird und das ul default ausgeblendet.

In seinem HTML sehe ich ein "hidden"-Attr. beim ul, nicht bei nav, wie er sagt. Nav scheint aber auch niemand sonst zu verwenden dafür. Alle blenden das ul aus und nehmen zum Verstecken/Ausblenden immer display: none, das am sichersten zu sein scheint.
Ansonsten scheint er gar nichts ein/auszublenden in seinem CSS? Weil mobile-first? Ich sehe auch gar kein MQ.

Die zwei Beispiele, die ich meinte, sind komplexer.

Das eine hat zusätzlich ein Logo und ein Suchfeld, was ich beides nicht brauche. Und es hat zusätzlich zwei DD-Untermenüs, die ebnfalls DD/Toggle-Buttons haben. Das wäre dann wie bei meiner anderen Site, die ich auch noch umstellen muss. Aber die jetzige hat keine Untermenüs:
https://www.freecodecamp.org/news/how-to-build-a-responsive-navigation-bar-with-dropdown-menu-using-javascript/

Das andere Beispiel hat keinen HTML-, sondern einen div-Button und obwohl das JS mit aria-expanded arbeitet, sehe ich keines beim div-Button im HTML!? Ansonsten erklärt es die Sachen recht ausführlich und wäre mein Fall (nur das Logo brauche ich nicht):
https://thesyntaxdiaries.com/responsive-navbar-html-css-js

Sehe ich es richtig, dass ich für meine zwei Navs zwei JavaScripts brauche (jedes mit ein paar Blöcken JS-Code) und man nicht in einem Code beide Navs gleichzeitig behandeln darf/kann/soll?

13.09.2025 18:54

4 Jörg Kruse

Nur kurz zu ein paar Fragen, da ich gleich ins Wochenedne gehe :) - die beiden komplexeren Beispiel schaue ich mir nach dem Wochenende genauer an (falls da noch Bedarf ist)

In seinem HTML sehe ich ein "hidden"-Attr. beim ul, nicht bei nav, wie er sagt. Nav scheint aber auch niemand sonst zu verwenden dafür.

Ja, weil dort der Toggle-Button innerhalb von nav liegt. Der Button soll ja sichtbar sein, wenn das Menü ausgeblendet ist.

Ansonsten scheint er gar nichts ein/auszublenden in seinem CSS? Weil mobile-first? Ich sehe auch gar kein MQ.

Du kannst in einer Media Query das Attribut hidden mit display:block in der Desktop-Ansicht überschreiben, z. B.:

@media only screen and (min-width: 768px) {
  .headnav-haupt-ul {
    display:block;
  }
  .headnav-button {
    display:none;
  }
}

Sehe ich es richtig, dass ich für meine zwei Navs zwei JavaScripts brauche (jedes mit ein paar Blöcken JS-Code) und man nicht in einem Code beide Navs gleichzeitig behandeln darf/kann/soll?

Jain, du benötigst nur ein JavaScript, aber der Ablauf muss zweifach mit unterscheidbaren Variablen erfolgen. Wenn ein Script für ein Menü taugt, könnte man dieses für zwei Menüs in einer Schleife laufen lassen. Beispiel für das von mir verlinkte Script und zwei Navigationen 'headnav' und 'sidenav':

const navToggle[0] = document.querySelector('.headnav-button');
const navList[0] = document.querySelector('.headnav-haupt-ul');
const navLinks[0] = document.querySelectorAll('.headnav-haupt-ul li a');

const navToggle[1] = document.querySelector('.sidenav-button');
const navList[1] = document.querySelector('.sidenav-haupt-ul');
const navLinks[1] = document.querySelectorAll('.sidenav-haupt-ul li a');

for (let i = 0; i <= 1; i++) {
    navToggle[i].addEventListener('click', function () {
        if (navList[i].hasAttribute('hidden')) {
            this.setAttribute('aria-expanded', 'true');
            navList[i].removeAttribute('hidden');
            navLinks[i][0].focus();
        } else {
            navList[i].setAttribute('hidden', 'true');
            this.setAttribute('aria-expanded', 'false');
        }
    });
}

document.addEventListener('keydown', (event) => {
    if (event.isComposing || event.keyCode === 229) {
        return;
    }
    if (event.keyCode === 27) {
        for (let i = 0; i <= 1; i++) {
            if (!navList[i].hasAttribute('hidden')) {
                navToggle[i].setAttribute('aria-expanded', 'false');
                navList[i].setAttribute('hidden', 'true');
            }
        }
    }
});

13.09.2025 20:49 | geändert: 13.09.2025 21:09

Beitrag schreiben (als Gast)

Die Antwort wird nach der Überprüfung durch einen Moderator freigeschaltet.





[BBCode-Hilfe]