CSS/Tutorials/Dropdown-Menüs mit CSS gestalten

Aus SELFHTML-Wiki
< CSS‎ | Tutorials(Weitergeleitet von CSS/Anwendung und Praxis/Menüs)
Wechseln zu: Navigation, Suche

Dieses Tutorial 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.

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 Festelgung 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. Alternativ können sie über nav ul ul selektiert werden.

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,
nav li:focus-within .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. Neben der Pseudoklasse :focus wird eine weitere Pseudoklasse :focus-within selektiert, die dafür sorgt, dass das Submenü eingeblendet bleit, wenn sich der Fokus vom Listenelement weg zu den Listeneinträgen des Submenüs bewegt.

Wenn Sie auf kleinen Viewports mit der Maus oder über die Tastatur ausgewählt werden, wird das Submenü eingeblendet; die folgenden Listenpunkte rutschen (wegen height: auto;) nach unten. Mobile Geräte haben zwar weder Maus noch Tab-Taste, ein Tap simuliert aber ein :hover, sodass dass Submenü angezeigt wird.

Das Beispiel ist nun für alle Geräte einsatzbereit. Man kann die Submenüs …

  • … mit der Maus problemlos auf- und zuklappen.
  • … auf Touch-Gräten mit kleinen Viewports problemlos auf- und durch Tap auf einen anderen Link zuklappen.
  • … mit der Tastatur die Submenüs über das tabindex des li-Elements sichtbar machen, und dann den dazugehörigen Link und die Listeneinträge des Submenüs durchtabben.

Was nicht funktioniert, ist …

  • … eine schnelle Tastatur-Ansteuerung der einzelnen Menüpunkte im Hauptmenü ohne den Umweg über die einzelnen Submenüs zu gehen
  • … eine Navigation der einzelnen Punkte mithilfe der Pfeiltasten

Hier gerät CSS an seine Grenzen und der Einsatz von JavaScript wird erforderlich.

Eine CSS-basierte Alternative bieten Menüs mit dem Checkbox-Hack, die jedoch auch Nachteile haben.

Deshalb sollten Sie eine zugängliche Navigation mit JavaScript erstellen:

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“

vertikales Flyout-Menü[Bearbeiten]

Das obere Beispiel 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 die media queries 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: 10em; rechts neben dem 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.

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 vorgestellte Navigation mit Maus; Touch und Tastatur ansteuern und bedienen.

Eine wirklich zugängliche und bei größeren Menüs komfortable Variante erreichen Sie aber nur mit JavaScript:

Siehe auch[Bearbeiten]