Ijs2019medienpartner.jpg

SELFHTML ist in diesem Jahr Medienpartner der IJC.

Für die Konferenz vom 21. – 25. Oktober 2019 in München verlosen wir ein Freiticket.

Weitere Informationen finden sich im SELFHTML-Forum.

HTML/Tutorials/Navigation/Dropdown-Menü

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Informationen zu diesem Text

Lesedauer
45min
Schwierigkeitsgrad
einfach
Vorausgesetztes Wissen
Grundkenntnisse in
● HTML
● CSS

Dieses Kapitel zeigt, wie Sie mithilfe von CSS Menüs und Navigationen gestalten können. Neben der benutzerfreundlichen Formatierung von Links lernen Sie, wie Sie eine Dropdown-Navigation erstellen, die sich mit Maus und Tastatur auf- und zuklappen lässt. Dabei passt sie sich responsiv an alle Viewports an.

Empfehlung: Folgender Artikel ist als Grundwissen zu empfehlen:
Beachten Sie: Im Tutorial wird die Funktionsweise einer Dropdown-Navigation erklärt. Das endgültige Aussehen kann später individuell per CSS angepasst werden.

Einfache Menüs[Bearbeiten]

HTML-Struktur[Bearbeiten]

Für die Navigationsleiste wird im Allgemeinen eine Aufzählungsliste verwendet. Hiermit haben Sie nicht nur ein strukturelles Element, das dem Sinn einer Navigation, nämlich der Auflistung von Verweisen, recht gut entspricht, sondern auch gleich drei verschachtelte Elemente, die Sie über CSS formatieren können: ul, li und a.

Damit wir das Menü unabhängig von anderen Listen und Verweisen formatieren können, setzen wir es in das HTML5-Element nav.

Hinweis

Navigationsleisten und Menüs mit Verweisen sollten mit dem nav-Element umschlossen werden.

Das menu-Element ist für Werkzeugleisten und Toolbars vorgesehen.

Beispiel: ein einfaches Menü ansehen …
<nav>
   <ul>
      <li><a href="#">Seite 1</a></li>
      <li><a href="#">Seite 2</a></li>
      <li><a href="#">Seite 3</a></li>
      <li><a href="#">Seite 4</a></li>
      <li><a href="#">Seite 5</a></li>
      <li><a href="#">Seite 6</a></li>
  </ul>
</nav>

Verweise zu Schaltfläche machen[Bearbeiten]

Damit wir jetzt anklickbare Schaltflächen bekommen, stylen wir die einzelnen Elemente mit CSS:

  • Entfernen der Aufzählungszeichen
  • Breite und Innenabstand
  • Hintergrund- und Textfarbe
Empfehlung: Um eine einheitliche Darstellung zu erreichen, können Sie zunächst die unterschiedlichen Voreinstellungen der Browser für Listen überschreiben (siehe auch Normalisierung).
Beispiel: ein einfaches Menü mit CSS, das den ausgewählten Link zeigt ansehen …
  nav ul {
    list-style: none; 	  
    width: 10em;
    border: 1px solid;
    background-color: silver;

  }
  nav li {
    margin: 0.5em; 
    border: 1px solid;
    background-color: #eee;
  }
  nav a {
    text-decoration: none; 
    font-weight: bold;
    color: gold; 
    background-color: darkblue;
  }
  nav a:focus,
  nav a:hover,
  nav a:active {    
    text-decoration:underline;
  }
In diesem Menü sind die einzelnen Elemente eingefärbt:
  • nav ul erhält einen silbernen Hintergrund und eine Breite von 10em. Mit list-style: none werden die Aufzählungspunkte entfernt. Beachten Sie den großen Innenabstand links vor den Listenelementen, der mit einer Festlegung von padding später entfernt wird.
  • nav li erhält einen grauen Hintergrund und mit margin einen Außenabstand zu den anderen Listenelementen
  • nav a verliert mit text-decoration: none; seine Unterstreichung und wird nun dunkelblau mit goldener Schrift dargestellt. Es fehlt allerdings noch das typische Balken-Aussehen, da a als Inline-Element nur den für seinen Inhalt erforderlichen Raum einnimmt.
  • nav a:focus, nav a:hover; Wenn Sie einen Link mit Maus oder Tastatur anwählen, wird die Unterstreichung wieder eingeblendet.
Beachten Sie: In diesem Beispiel sind Verweise durch die farbigen Schaltflächen als solche erkennbar. Ausgewählte Verweise sind nur durch den geänderten cursor bei Geräten mit Mausbedienung und die Unterstreichung erkennbar.
Kennzeichnen Sie Links als solche immer mit mindestens zwei gut erkennbaren Merkmalen wie z.B. Unterstreichung oder blaue Textfarbe!

Rollover-Effekt[Bearbeiten]

Linkelemente können per Maus oder per Tastatur ausgewählt werden. Über die Pseudoklasse :hover bzw. :focus können Sie ausgewählte Elemente selektieren und ihre Formatierung ändern.

Beispiel: Rollover-Effekt ansehen …
    nav a {
      display: block;
      padding: 0.4em;
      text-decoration: none; 
      font-weight: bold;
      border: 1px solid darkblue;
      border-radius: 10px;
      box-shadow: 0 5px 10px white inset;
      color: gold; 
      background-color: darkblue; 
      transition: all .25s ease-in;	  
    }

  nav li[aria-current] a {
	background-color: firebrick; 
    color: gold;
  }
	
    nav a:focus,
    nav a:hover,
    nav li[aria-current] a:focus,
    nav li[aria-current] a:hover {    
      color: darkblue; 
      background-color: gold;
    }
Durch display: block nimmt das Linkelement die gesamte zur Verfügung stehende Breite (=Breite des Listenelements innerhalb der 10em breiten Liste) ein.
Ausgewählte Verweise werden durch eine Änderung der Hintergrundfarbe (sowie dazu passend der Schriftfarbe) gekennzeichnet. Hierdurch ergibt sich ein Rollover-Effekt. Um dies eleganter wirken zu lassen, wird die Farbänderung bei :hover oder :focus durch transition um 0.25 Sekunden verzögert, so dass ein Nachglüh-Effekt entsteht.
Neu in diesem Beispiel hinzugekommen ist auch, dass die aktuelle Seite nicht verlinkt wird. Dies erleichtert die Benutzbarkeit, da der Standort erkennbar ist und nicht mit einem (in diesem Fall ja nutzlosen) Link verwechselt werden kann. Hierzu wird das Link-Element für den aktuellen Menüpunkt durch ein aria-Attribut ergänzt.

Vertikal oder horizontal?[Bearbeiten]

Sie können eine Navigationsleiste mit wenigen Menüpunkten auch horizontal anordnen (Quernavigation). Hierfür existieren mehrere verschiedene Möglichkeiten mit unterschiedlichen Vor- und Nachteilen. Die einfachere Möglichkeit ist, die li-Elemente per display: inline darzustellen. Dies ermöglicht auch deren Zentrierung über eine auf das Eltern-Element angewandte Eigenschafts-/Wertkombination von text-align: center.

Beispiel: horizontale Formatierung der Listenelemente
nav ul {
    text-align: center;
    /* weitere Angaben */
}

nav li {
    display: inline-block;
    /* weitere Angaben */
}

Einen Nachteil hat diese Methode jedoch: Bei einem Umbruch der Navigationsleiste in zu kleinen Browserfenstern kommt es zu Überlagerungen. Dieser Effekt kann zwar auch bewusst zu gestalterischen Zwecken eingesetzt werden, verschlechtert allerdings die Nutzbarkeit. Achten Sie darauf, dass in den Menütexten kein Zeilenumbruch stattfindet. Falls die Menüpunkte Leerzeichen enthalten, können Sie mithilfe von white-space: nowrap; den automatischen Zeilenumbruch verbieten.

Responsive Navigation[Bearbeiten]

Besser wäre es, wenn sich die Navigation bei einem genügend großen Viewport horizontal anordnen würde, auf kleineren Geräten jedoch weiterhin untereinander positioniert würde.

Dafür eignen sich das neue Grid Layout oder Flexbox.

Beispiel: Responsive Navigation ansehen …
nav ul {
  display: flex;
  flex-direction: column;
} 

nav li {
  list-style: none;
  margin: 0.5em;
  padding: 0;
  font-size: 1.5em;  
}

@media (min-width: 45em) {
  nav ul {	
    flex-direction: row;  
  }
  nav li {
    font-size: 1em;
  }  
}
  • nav ul wird mit display: flex; zum Flex-Container, in dem die Kindelemente durch flex-direction: column; untereinander angeordnet werden.
  • nav li erhält mit font-size: 1.5em eine größere Schriftgröße, dass die Schaltflächen auch auf kleinen Viewports groß genug sind.
  • In einer media query wird für größere Viewports ab 45em Breite eine andere Formatierung festgelegt:
    • flex-direction: row; wechselt auf horizontale Darstellung innerhalb einer Reihe.
    • nav li erhält wieder die „normale“ Schriftgröße
Dieses Beispiel verzichtet auf feste Breiten. Diese werden je nach Platz vom Brwoser festglegt!
Empfehlung: Öffnen Sie dieses Beispiel mit Rechtsklick in einem neuen Tab und verändern sie die Größe des Browserfensters.

Menüs mit mehreren (geschachtelten) Ebenen[Bearbeiten]

Navigationen bei größeren Webprojekten enthalten in vielen Fällen keine sequenzielle Auflistung von Links, sondern verteilen diese auf verschiedene Navigationsebenen.

verschachtelte Listen[Bearbeiten]

Zur logischen Abbildung dieser Struktur eignen sich verschachtelte Listen.

Beispiel: verschachtelte Listen (ohne CSS) ansehen …
<nav>
  <ul>
    <li><a href="#">Seite 1</a></li>

    <li><a href="#">Seite 2</a>
      <ul>
        <li><a href="#">Seite 2a</a></li>
        <li><a href="#">Seite 2b</a></li>
      </ul>
    </li>

    <li aria-current="page"><a href="#">aktuelle Seite</a></li>

    <li><a href="#">Seite 4</a>
      <ul>
        <li><a href="#">Seite 4a</a></li>
        <li><a href="#">Seite 4b</a></li>
        <li><a href="#">Seite 4c</a></li>
      </ul>
    </li>

    <li><a href="#">Seite 5</a></li>
    <li><a href="#">Seite 6</a></li>
  </ul>
</nav>
In das zweite und vierte li-Element ist hier eine weitere Liste eingefügt, da Listen wie ul oder ol selbst keine anderen Elemente als li als direktes Nachfahrenelement enthalten dürfen.

Selbst ohne CSS wird die Struktur von verschachtelten Listen über die Browser-Voreinstellungen sehr gut deutlich.

Mit der Tastatur können alle Links ausgewählt werden.


Beispiel: verschachtelte Listen (mit CSS) ansehen …
nav > ul {
 ...
} 

@media (min-width: 45em) {
  nav > ul {	
    ...  
  }
}
Die Formatierung der ersten Navigationsebene bleibt erhalten. Damit nur die Elemente der ersten Ebene angesprochen werden, werden sie über den Kindselektor nav > ul selektiert.
Die Listen der zweiten Ebene erhalten eine Klasse submenu.

Flyout oder Dropdown?[Bearbeiten]

Zu Zeiten des pixelgenauen Layouts gab es nun zwei Varianten:

  • Bei einem Flyout-Menü „fliegen“ die Untermenüs aus der vertikalen Struktur horizontal nach rechts heraus
  • Bei einem Dropdown-Menü „fallen“ die Untermenüs aus der horizontalen Reihe vertikal „herunter“

Submenü ausblenden[Bearbeiten]

Kennzeichen eines Dropdown-Menüs ist, dass das Submenü im Originalzustand ausgeblendet ist und erst beim Auswählen mit der Maus über die Pseudoklasse :hover oder mit der Tastatur über :focus selektiert und sichtbar gemacht wird.

Beispiel: Navigationsleiste mit mehreren Ebenen ansehen …
/*     submenu navigation links      */
nav .submenu { 
  visibility: hidden;  
  height: 0;
  z-index: 1000; 
}
nav .submenu li { 
  display: block; 
  width: 15em;
}
 
/**     Show the submenu on hover, focus     **/
nav li:hover  .submenu,
nav li:active  .submenu, 
nav li:focus  .submenu { 
  visibility: visible;
  height: auto;
}
Die Listen der zweiten Ebene erhalten eine Klasse submenu, die im Normalzustand mit visibility: hidden ausgeblendet ist.

Listenelemente, die als Kindelement ein Submenü beinhalten, erhalten einen tabindex="0", damit sie antabbar sind.

Wenn Sie mit der Maus oder über die Tastatur ausgewählt werden, wird das Submenü eingeblendet; die folgenden Listenpunkte rutschen nach unten.

ToDo (weitere ToDos)

Das Beispiel funktioniert nicht wie gewünscht.
  • Man kann zwar die Submenüs über das tabindex des li-Elements sichtbar machen, die Listeneinträge jedoch nicht mit der Tastatur durchtabben.
  • Wenn man über den Geschwisterselektor a:hover ~ .submenu selektiert, wird das Submenu ein- , sobald der erste Listenpunkt angewählt wird, aber doch wieder ausgeblendet.
--Matthias Scharwies (Diskussion) 08:09, 31. Okt. 2017 (CET)



ToDo (weitere ToDos)

Integrieren oder weg --- Matthias Scharwies (Diskussion) 08:49, 31. Okt. 2017 (CET)

vertikales Flyout-Menü[Bearbeiten]

Dieses Menü kann mit wenigen Handgriffen zu einem vertikalen Flyout-Menü umgebaut werden:

Beispiel: vertikales Flyout-Menü ansehen …
  nav ul {
    margin: 0;
    padding: 0;
    text-align: center;
  }

  nav li {
    list-style: none;
    position: relative;
    margin: 0; 
    padding: 0;
  }

  nav ul ul {
    position: absolute;
    top: -0.4em; 
    left: 8em;
  }

Durch den Verzicht auf nav li {float:left} ordnen sich die Menüpunkte untereinander an. Die absolute Position von nav ul ul gleicht mit top: -0.4em; das padding des Elternelements aus und wird mit left: 8em; rechts neben das Elternelement positioniert.

Diese Art der Navigation ist heute etwas verpönt, da dem Inhaltsbereich die ganze Breite zukommen soll. Lesestudien haben ergeben, dass Nutzer intuitiv links anfangen, neue und wichtige Informationen zu suchen und so von der Navigation eher abgeschreckt werden.

Vorteil dieser Art der Navigation ist, dass lange Links einfach integriert werden können, die in einer horizontalen Navigation nicht untergebracht werden könnten. Ein weiteres Plus ist das einfache Erweitern nach unten, welches aber nach mehreren Änderungen schnell zu lang und unübersichtlich werden kann. Beide Vorteile bergen also Gefahren, die Navigation unübersichtlich und schlecht benutzbar werden zu lassen.

Beachten Sie: Da Listenelemente nicht per Tastatur angesprungen werden können, ist diese Navigation nicht mit der Tastatur bedienbar. Abhilfe schafft die Verwendung von tabindex.
Empfehlung: Ordnen Sie Ihre Seiten in einer klaren und logischen Struktur mit nur wenigen Menüpunkten. Erweitern Sie diese nur im Notfall.


Exkurs: Elemente ausblenden (Alternativen zu display:none)[Bearbeiten]

Das Ausblenden der Untermenüs mit display: none; (und Einblenden mit display: block;) sollte man vermeiden, weil das die Inhalte für Benutzer von Screenreadern versteckt.

Eine Alternative ist es, die Untermenüs mit margin-left:-9999px; außerhalb des sichtbaren Bereichs zu verschieben und von dort wieder einfliegen zu lassen. Allerdings erzeugen die Browser dann ein zwar unsichtbares, aber riesengroßes Element, was die Performance der Seite negativ beeinflusst.

Ein anderer Weg könnte sein, das Untermenü mit text-indent unsichtbar zu machen:

Beispiel: text-indent blendet Element aus
nav ul ul {
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

Vorteil ist, dass der Text immer vom Element wegfließt und so auch bei langen Texten nie hereinragen kann und das kein 9999px großer Container gezeichnet werden muss. Gerade auf mobilen Geräten ist die Performance deutlich besser.

Eine dritte Möglichkeit schiebt den Menüpunkt mit einem negativen z-index hinter die Seite. Damit er auch tatsächlich verschwindet, bekommt er noch eine Schriftgröße von Null.

Beispiel: font:0/0; und z-index blenden Element aus
nav ul ul {
   font: 0/0 serif;   /* Unternavigation ausblenden */
   z-index: -1;
}

nav ul li:hover ul {
   font: inherit;     /*  Unternavigation einblenden */
   z-index: auto;   
  }

Fazit[Bearbeiten]

Sie können die hier vorgestellten Navigationen mit der Maus ansteuern und bedienen. Mit der Tastatur können Sie nur die dargestellten, aber nicht die ausgeblendeten Verweise ansteuern.

Für mobile Geräte sind die Navigationen zu breit, sodass sie mit Hilfe von Media Queries in einer responsive Ansicht umgeschaltet werden müssen.


Eine wirklich zugängliche Variante erreichen Sie nur mit JavaScript: