CSS/Anwendung und Praxis/Dropdown-Menüs mit CSS gestalten

Aus SELFHTML-Wiki
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 auf- und zuklappen lässt.

Inhaltsverzeichnis

[Bearbeiten] Einfache Menüs

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>
  </ul>
</nav>

[Bearbeiten] Den Verweis zu einer Schaltfläche machen

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, sind zunächst die unterschiedlichen Voreinstellungen der Browser für Listen zu überschreiben (siehe auch Normalisierung).
Beispiel: ein einfaches Menü mit css, das den ausgewählten Link zeigt ansehen …
nav,                     
  nav ul,
  nav li {           /* Normalisierung */
    list-style: none; 
    margin: 0; 
    padding: 0;
    border: 0;
  }
  nav ul {
    width: 10em;
    padding: 0.8em;
    border: 1px solid black;
    background-color: silver;
  }
  nav li {
    margin: 0.4em; 
    padding: 0.2em;
    border: 1px solid gray;
    background-color: #eee;
  }
  nav a {
    text-decoration: none; 
    font-weight: bold;
    color: gold; 
    background-color: royalblue;
  }
  nav a:focus,
  nav a:hover,
  nav a:active {    
    color: royalblue; 
    background-color: gold;
  }

[Bearbeiten] ausgewählte Elemente einer Liste markieren

Linkelemente können per Maus oder per Tastatur ausgewählt werden. Diesen wurde eine Hintergrundfarbe zugewiesen und diese (sowie dazu passend die Schriftfarbe) über die Pseudoklasse :hover bzw. :focus geändert. Hierdurch ergibt sich ein Rollover-Effekt. Es fehlt allerdings noch das typische Balken-Aussehen, da a als Inline-Element nur den für seinen Inhalt erforderlichen Raum einnimmt.

Beispiel: Nr.3 ansehen …
nav a {
  display: block;
  padding: 0.4em;
  text-decoration: none; 
  font-weight: bold;
  border: 1px solid blue;
  border-radius: 10px;
  box-shadow: 0 5px 10px white inset;
  color: gold; 
  background-color: royalblue;
}
 
nav a:focus,
nav a:hover {
  color: royalblue; 
  background-color: gold;
  border-color: gold;
}
Durch display: block nimmt das Linkelement die gesamte zur Verfügung stehende Breite ein.

[Bearbeiten] Vertikale Formatierung mit Überschriften

Eine größere Anzahl von Menüpunkten in einer vertikal dargestellten Navigation ist aufgeteilt in Rubriken mit Zwischenüberschriften übersichtlicher. Hierzu werden im folgenden Beispiel h2-Elemente in die Liste eingefügt und ihnen gemeinsam mit den Links zunächst dieselben CSS-Eigenschaften zugewiesen.


Beispiel: Nr.4 Rubriken und aktuelle Seite ansehen …
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Beispiel 4: Navigationsleiste mit Überschriften</title>
    <style type="text/css">
      body {
        font: normal 1em Helvetica, Arial, sans-serif;
      }
 
      nav ul {
        width: 10em;
        margin: 0; 
        padding: 0.2em 0.8em 0.8em;
        border: 1px solid black;
        background-color: silver;
      }
 
      nav li {
        list-style: none;
        margin: 0.4em; 
        padding: 0;
      }
 
      nav a, nav span, nav h2 {
        display: block;
        padding: 0.4em;
        text-decoration: none; font-weight: bold;
        border: 1px solid blue;
        border-radius: 10px;
        box-shadow: 0px 5px 10px white inset;
        color: gold; 
        background-color: royalblue;
      }
 
      nav a:focus,
      nav a:hover,
      nav a:active,
      nav span {
        color: royalblue; 
        background-color: gold;
        border-color: gold;
      }
      nav h2 {
        font-size: 1em;
        margin: 1.1em 0 0;
        color: black;
        border-color: transparent;
        background-color: transparent;
        box-shadow:n one;
      }
    </style>
  </head>
  <body>
    <h1>Beispiel 4: Navigationsleiste mit Überschriften</h1>
 
    <nav>
      <ul>
        <li><h2>Rubrik 1</h2></li>
        <li><a href="#">Beispiel 1</a></li>
        <li><a href="#">Beispiel 2</a></li>
        <li><a href="#">Beispiel 3</a></li>
 
        <li><h2>Rubrik 2</h2></li>
        <li><span>aktuelle Seite</span></li>
        <li><a href="#">Beispiel 5</a></li>
        <li><a href="#">Beispiel 6</a></li>
      </ul>
    </nav>
 
  </body>
</html>

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 für den aktuelle Menüpunkt in diesem Beispiel das Link-Element durch ein span-Element ersetzt. In unserem Fall hat der Menüpunkt der aktuellen Seite dieselbe Formatierung, wie ein angewählter Link; Sie können ihn - ausgehend von der Basisformatierung - auch noch deutlicher hervorheben.

[Bearbeiten] Verlinke nicht auf die aktuelle Seite

Um diese Forderung umzusetzen gibt es mindestens die in der folgenden Tabelle dargestellten Möglichkeiten.

HTML CSS Bemerkungen
<li><a href="#">
  <!-- normaler Menüpunkt -->
<li class="current"><a href="#">
  <!-- aktuelle Seite -->
nav li { }
  /* normaler Menüpunkt */
nav.current li { } 
  /* aktuelle Seite */
Eine Klassenbezeichnung ist im allgemeinen nicht notwendig, der häufig anzutreffende Klassenbezeichner "active" wäre sogar verkehrt.
<li><a href="#">
  <!-- normaler Menüpunkt -->
<li><span>
  <!-- aktuelle Seite -->
nav li { }
  /* normaler Menüpunkt */
nav span { } 
  /* aktuelle Seite */
<li><a href="#">
  <!-- normaler Menüpunkt -->
<li>
  <!-- aktuelle Seite -->
nav li { }
  /* aktuelle Seite */
nav a { } 
  /* normaler Menüpunkt */
Diese Variante erfordert ein Umdenken im CSS. Man stylt zuerst das Spezielle und dann das Allgemeine.
<li><a href="#">
  <!-- normaler Menüpunkt -->
<li><a>
  <!-- aktuelle Seite -->
nav a { }
  /* aktuelle Seite */
nav a[href] { } 
  /* normaler Menüpunkt */
Auch in diesem Fall stylt man vom Speziellen zum Allgemeinen. Semantisch nicht ganz exakt, denn ein Link-Element ohne href-Attribut ist kein Link.
Beispiel: Nr.4 Neon-Navigation mit Nachglüh-Effekt ansehen …
  nav a {
    color: darkseagreen;
    background-color: #303728;
    transition: background-color .25s ease-in;
  }
 
  nav a:focus, nav a:hover, nav span {
    color: #303728; 
    background-color: greenyellow;
    transition: background-color 0.01s;
  }

In dieser Variante wird die Farbänderung bei :hover oder :focus durch transition um 0.3 Sekunden verzögert, so dass ein Nachglüh-Effekt entsteht.

[Bearbeiten] Horizontale Formatierung

Sie können eine Navigationsleiste mit wenigen Menüpunkten auch horizontal anordnen (Quernavigation). Hierfür existieren zwei 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 ansehen …
nav ul {
    text-align: center;
    /* weitere Angaben */
}
 
nav li {
    display: inline-block;
    /* weitere Angaben */
}
 
nav a, nav span {
    display: block;
    width: 8em;
    /* weitere Angaben */
}


Da inline-Elementen keine Breite zugewiesen werden kann, richtet sich diese nach dem enthaltenen Text. Deshalb setzen wir die a-Elemente auf display: block; und geben ihnen alle die gleiche Breite.

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.

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

Eine Navigation, die wie in Beispiel Nr.4 mit Zwischenüberschriften versehen ist, wird in vielen Fällen keine sequenzielle Auflistung von Links enthalten, sondern eher verschiedenen Navigationsebenen entsprechen. Die Überschriften stellen in diesem Fall die Hauptmenüpunkte dar und können selbst auch mit Übersichtsseiten für die jeweilige Rubrik verlinkt sein. Eine verschachtelte Liste eignet sich zur logischen Abbildung dieser Struktur jedoch besser.


Beispiel: Navigationsleiste mit mehreren Ebenen ansehen …
<nav>
  <ul>
      <li><a href="#Beispiel">Seite 1</a></li>
      <li><a href="#Beispiel">Seite 2</a>
        <ul>
          <li><a href="#Beispiel">Seite 2a</a></li>
          <li><a href="#Beispiel">Seite 2b</a></li>
          <li><a href="#Beispiel">Seite 2c</a></li>
        </ul>
      </li>
      <li><a href="#Beispiel">Seite 3</a></li>
      <li><a href="#Beispiel">Seite 4</a></li>
  </ul>
</nav>

In das zweite 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 darf.

Über die Nachfahren-Selektoren nav ul ul und nav ul ul li werden die CSS-Eigenschaften für die so verschachtelte Liste dahingehend geändert, dass die Menüpunkte dieser zweiten Ebene eingerückt und entsprechend schmaler sind und einen geringeren Abstand zueinander sowie zum dazugehörigen Menüpunkt der ersten Ebene aufweisen. Es sind natürlich auch andere CSS-Formatierungen möglich, um diese Struktur zu visualisieren.

Selbst ohne CSS wird die Struktur von verschachtelten Listen über die Browser-Voreinstellungen sehr gut deutlich, wie dieses Beispiel zeigt.


[Bearbeiten] horizontal und vertikal kombiniert

Eine verschachtelte Liste lässt sich auch geteilt darstellen, sodass die Menüpunkte der ersten Ebene horizontal in einer Reihe und die der zweiten Ebene vertikal passend darunter angeordnet werden. Dazu ist es erforderlich, die li-Elemente der ersten Ebene zum Beispiel per float nebeneinander anzuordnen und ihnen position: relative zuzuweisen, damit deren Positionen als Bezug für die über position: absolute aus dem Elementenfluss genommenen Listenpunkte der zweiten Ebene genutzt werden.


Beispiel: Navigationsleiste mit mehreren Ebenen ansehen …
nav li {
  float: left;
  position: relative;
}
 
nav ul ul {
  position: absolute;
  top: 1.7em; 
  left: -0.4em;
}
 
nav ul ul li {
  float: none;
  display: block;
}

Bei dieser Navigationsleiste muss ein Umbruch verhindert werden, um die richtige Reihenfolge der angezeigten Menüpunkte zu gewährleisten. Dazu ist eine ausreichend große Breite anzugeben, die allerdings nicht der Liste selbst zugewiesen werden sollte, da dies in einigen Browsern zu einer fehlerhaften Darstellung führt. Daher wird dem nav-Element die Breite und die Definitionen für den Rahmen und die Hintergrundfarbe zugewiesen.

Da die Listenpunkte über float aus dem Elementfluss genommen sind, muss ein zusätzliches, innerhalb des Rahmens notiertes Element mit der CSS-Eigenschaft clear den Elementfluss wieder herstellen. Hierzu verwenden wir ein ansonsten leeres Pseudoelement nav:after {content:''; clear: left;}.

Die verschachtelten Listen der zweiten Ebene werden über den Nachkommen-Selektor nav ul ul absolut unterhalb des dazugehörigen Listenpunktes positioniert. Für die Listenpunkte der zweiten Ebene wird über den Nachkommen-Selektor nav ul ul li die Eigenschaft float aufgehoben.

In diesem Beispiel ist ein Menüpunkt der zweiten Ebene als aktuelle Seite nicht verlinkt, sondern mit dem Element ausgezeichnet und über CSS gesondert formatiert. Um auch den dazugehörigen Menüpunkt der ersten Ebene über CSS hervorheben zu können, wird für diesen die id="aktuell" angegeben.


[Bearbeiten] Dropdown-Menü mit CSS

Drop-Down-Menüs sind Menüs, bei denen im Originalzustand nur die übergordneten Menüpunkte sichtbar sind. Erst ein Klick oder Touch auf diese Menüpunkte lässt untergeordnete Listen der zweiten Ebene dynamisch einblenden. Hierzu ist nur eine kleine Ergänzung im Stylesheet erforderlich:

Beispiel: Dynamisch Navigationsleisten einblenden ansehen …
nav ul ul {
  margin: 0; 
  padding: 0;
  position: absolute;
  top: 2.2em; 
  font: 0/0 serif;/* Unternavigation ausblenden */
  z-index: -1;
}
 
nav ul li:hover ul {
  font: inherit;
  z-index: auto;   /*  Unternavigation einblenden */
}


Über den Selektor nav ul ul werden die Listen der zweiten Ebene zunächst ausgeblendet. (Sollten weitere Verschachtelungen vorhanden sein, muss das CSS entsprechend angepasst werden) Beim Überfahren mit der Maus werden sie über den Selektor nav ul li:hover ul mit wieder angezeigt. Damit die beim Überfahren mit der Maus eingeblendete Liste beim Ansteuern ihres ersten Menüpunktes nicht wieder ausgeblendet wird, muss sie etwas höher positioniert werden, sodass sie den Listenpunkt der ersten Ebene überlappt. Wenn Sie genau hinsehen, bemerken Sie hier einen etwas geringeren Abstand als den über margin für die verschachtelten Listenpunkte angegebenen.

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.

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

Hinweis

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;   
  }

Dies wird in unseren Beispielen verwendet.

[Bearbeiten] vertikales Flyout-Menü

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 postioniert.

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.

[Bearbeiten] Fazit

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:

[Bearbeiten] Siehe auch

Meine Werkzeuge
Namensräume

Varianten
Aktionen
Übersicht
Schnell‑Index
Mitmachen
Werkzeuge
Spenden
SELFHTML