Vor einigen Tagen habe ich in diesem Beitrag eine Möglichkeit aufgezeigt, wie ein horizontales Dropdown-Menü erstellt werden kann. Was auf Desktop-Rechnern mit Maus-Bedienung perfekt funktioniert, ist auf Touch-Geräten ungeeignet, da es kein mouseover gibt und sich daher Untermenüs nicht öffnen lassen.

Was also tun, um der immer größer werdenden Zahl von Besuchern mit mobilen Geräten die Navigation eurer Webseite nutzbar zu machen? Eine Möglichkeit ist es die Navigation abhängig von der Auflösung anzupassen und ab einer bestimmten Bildschirmbreite das Menü auf „touch-friendly“ umzuschalten.

Und das soll unser Ziel sein, wobei der Ausgangspunkt das folgende Menü aus dem oben erwähnten Beitrag ist:

See the Pen Ein horizontales Dropdown-Menü by Oliver (@reap705) on CodePen.

So wird das Ergebnis aussehen (und das ganz ohne Javascript oder ähnliches):

See the Pen Ein horizontales Dropdown-Menü (responsive) by Oliver (@reap705) on CodePen.

Zum Thema „responsives Layout“ habe ich schon einmal eine kurze Einführung veröffentlicht. Hier ein kurzes Beispiel, um die Funktionsweise zu demonstrieren:

wir haben für unsere Webseite eine Standard-Schriftgröße von 12 Pixeln festgelegt:

html,
body {
  font-size: 12px;
}

Auf Geräten mit geringer Auflösung vielleicht ein wenig klein, oder? Um die Schriftgröße für Geräte mit weniger als 800 Pixel Breite auf 16 Pixel zu erhöhen, fügen wir folgende Anweisung hinzu:

@media screen and (max-width: 800px) {

html,
body {
  font-size: 16px;
}

}

Um es kurz und knapp zu erklären: Geräte, auf die diese Bedingung (< 800 Pixel Breite) zutrifft, nutzen die Anweisungen, die innerhalb davon gemacht sind und ignorieren insoweit die Anweisungen außerhalb davon.

So, genug Vorgeplänkel. Wie bekommen wir nun unser Menü responsive?

Anpassung des Quellcodes

Wir müssen den Quellcodes des Ursprungsmenüs erweitern, da das responsive Menü den sogenannten Checkbox-Hack nutzt, wofür wiederum ein Kontrollkästchen (checkbox) mit entsprechendem Beschriftungsfeld (label) benötigt wird.

Vor dem eigentlichen Menü, also vor dem Element nav, fügen wir hinzu:

<input type="checkbox" id="responsive-nav">
<label for="responsive-nav" class="responsive-nav-label"><span>&#9776;</span>Navigation</label>

Das Label dient später zum auf- und zuklappen des Menüs. Als Beschriftung bekommt das Label ein HTML-Menü-Zeichen (Hamburger-Button) sowie die Beschriftung „Navigation“.

Der Rest des Quellcodes bleibt unverändert.

Dieser kleine Trick mit dem zweckentfremdeten Kontrollkästchen klappt übrigens prima, sowohl auf Desktops als auch auf Touch-Geräten.

Erweiterung der Style-Deklarationen

Der Hauptpart kommt den Style-Anweisungen zu. Hier definieren wir zunächst, wann, also bei welcher Auflösung, das Menü responsive dargestellt werden soll. In unserem Beispiel soll das bei einer Anzeige-Breite von 1024 Pixeln oder weniger der Fall sein.

Wir fügen neu hinzu:

@media screen and (max-width: 1024px) {

}

In diesen Bereich kommen nun die CSS-Anweisungen, die ausgeführt werden, wenn die Anzeige-Breite 1024 Pixel oder weniger beträgt. Ist die Breite höher als 1024 Pixel, werden die Anweisungen nicht ausgeführt und das Menü normal als Dropdown mit Untermenüs dargestellt.

Bevor wir nun in die Vollen gehen, müssen wir noch eine Kleinigkeit an den Anweisungen für das nicht-responsive Menü ergänzen. Da wir im Quellcode ein Kontrollkästchen mit Label eingefügt haben, das Kontrollkästchen aber gar nicht und das Label nur bei einer Auflösung von weniger als 1024 Pixel zu sehen sein soll, blenden wir beides zunächst einmal aus.

input#responsive-nav,
label.responsive-nav-label {
  display: none;
}

Da das nun erledigt ist, machen wir uns nun an die Deklarationen, die das Menü responsive machen. Nochmal zur Erinnerung: in den Bereich

@media screen and (max-width: 1024px) {

}

kommen die (folgenden) Anweisungen dafür:

Wir beginnen beim Label, welches wir gerade ausgeblendet haben. Um das Label bei weniger als 1024 Pixel einzublenden, notieren wir folgendes:

label.responsive-nav-label {
  position: relative;
  display: block;
  padding: 20px;
  background: #222;
  cursor: pointer;
  color: #fff;
}

Das Label bekommt eine etwas dunklere Hintergrundfarbe als das Menü. Mit der Anweisung cursor: pointer; verändern wir den Mauspfeil, so dass er auf dem Label wie ein Link angezeigt wird. So signalisieren wir dem Besucher: hier gibt’s was zu klicken.

Das Menü-Symbol haben wir im Quellcode als span-Element eingefügt. So können wir einen Abstand zwischen Symbol und Beschriftung „Navigation“ einfügen:

label.responsive-nav-label span {
  margin-right: 10px;  
}

Wie schon erwähnt, soll das responsive Menü nur dann zusehen sein, wenn das Kontrollkästchen aktiviert ist, oder praktisch ausgedrückt, wenn auf das Label des Kontrollkästchens geklickt wird. Dafür tragen wir folgende Anweisung ein:

nav {
  position: absolute;
  top: -9999px;
  padding: 10px;
}

input#responsive-nav[type=checkbox]:checked ~ nav {
  position: relative;
  top: 0;
}

Das Element nav wird zunächst absolut außerhalb des Bildbereichs positioniert. Wenn das Kontrollkästchen aktiviert wird, also auf das Label geklickt wird, wird das Element relativ unterhalb des Labels positioniert.

Im responsiven Menü sind die Pfeile, die auf ein Untermenü hinweisen, deplatziert. Mit

nav a:after {
  display: none;
}

blenden wir diese aus.

Die Listenelemente, also auch die aus Untermenüs, sollen im responsiven Menü identisch untereinander dargestellt werden. Das erreichen wir durch folgende Anweisungen:

nav li {
  float: none !important;
  width: 100% !important;
  border-bottom: none !important; 
}
  
nav li a {
  margin-bottom: 10px !important;
  padding: 10px 20px !important; 
  background: #4a4a4a;
}

nav ul li:hover {
  background: none;
}
  
nav ul li a:hover {
  background: #4096ee;
}

Die Listenelemente des responsiven Menüs werden nicht gefloatet, bekommen 100% Breite und erhalten eine dunkle Hintergrundfarbe. Durch den Zusatz !important weisen wir den Browser an alle abweichenden Deklarationen des entsprechenden Elements zu ignorieren.

Im letzten Schritt müssen wir die Untermenüs umpolen. Wenn ihr euch noch erinnert, haben wir diese im Dropdown-Menü absolut außerhalb des Sichtbereichs positioniert und erst bei :hover waren diese dann sichtbar. Damit diese permanent innerhalb des responsiven Menüs angezeigt werden, positionieren wir alle Untermenüs relativ oben links mit einer Breite von 100%. Die Hintergrundfarbe sowie den Schlagschatten entfernen wir:

nav ul ul {
  position: relative !important;
  width: 100%;
  left: 0 !important;
  top: 0 !important;
  background: none !important;
  box-shadow: none;
}

Fertig. Damit wird unser Menü nun responsive und Touch-freundlich bei einer Auflösung von weniger als 1024 Pixeln Breite angezeigt.

Einen hab ich doch noch: sämtliche Listenelemente, ob Hauptmenüebene oder Untermenüebene, werden linksbündig ausgerichtet. So ist nicht zu erkennen, ob es sich um Hauptmenüpunkte oder Untermenüpunkte handelt. Wen das stört kann den Listenelementen der Untermenüs noch einen Innenabstand nach links geben:

nav ul ul li {
  padding-left: 20px;
}

So ist das Menü strukturiert und Untermenüs und Untermenüpunkte gut erkennbar.

Wie immer gilt: mach mit meinem Beispiel-Code was du willst. Es gibt keinerlei Copyright, egal ob du es privat oder gewerblich nutzt. Viel Spaß damit.

Update 26.08.2016

Justus hat mich darauf hingewiesen, dass ich vergessen habe folgende Deklaration in den Beitrag aufzunehmen, welche aber im Menü auf Codepen vorhanden ist:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

Hole ich gerne nach und will ich auch kurz erläutern: hiermit setzen wir die browserseitige Vorgabe für Außen- und Innenabstände auf 0. Mit box-sizing manipulieren wir das Box-Modell, und der Außenabstand wird nicht zur Boxgröße hinzugerechnet.

Also Justus, Danke für deinen Hinweis.