Responsive Navigation mit Progressive Enhancement

In diesem Beitrag erstellen Sie eine responsive Navigation, die immer funktioniert: Ohne JavaScript sehen die Besucher eine vertikale Navigationsliste, mit JavaScript gibt es einen Menübutton, der die Navigation bei Berührung sanft einblendet. In breiten Viewports bekommen die Besucher eine horizontale Navigation.

Inhaltsverzeichnis

»Progressive Enhancement«: ohne JS funktioniert’s, mit ist es besser

Das HTML für die Navigation besteht aus einem nav-Element, einem Button und einer Linkliste:

<!-- Das HTML für die Navigation --> 
<nav class="site-nav">

  <button class="menubutton" onclick="this.classList.toggle('showmenu')">Menü</button>

  <ul>	
    <li class="current"><a href="index.html">Startseite</a></li>	
    <li><a href="news.html">News</a></li>	
    <li><a href="ueber-uns.html">Über uns</a></li>	
    <li><a href="kontakt.html">Kontakt</a></li>	
  </ul>	

</nav>

Die responsive Navigation in Kapitel 23 von »Einstieg in HTML und CSS«

In schmalen Viewports wird die Navigationsliste ausgeblendet und Besucher sehen nur einen Menübutton. Beim Berühren des Menübuttons wird im HTML per JavaScript die Klasse showmenu hinzugefügt, mit deren Hilfe die Navigationsliste dann im CSS eingeblendet wird. Ab einer Viewportbreite von 600px wird die Navigationsliste horizontal dargestellt.

Diese Navigation ist eine clevere Kombination von HTML, CSS und JavaScript, hat aber den Nachteil, dass der Menübutton ohne JavaScript nicht funktioniert. Die Navigationsliste wird in dem Fall trotz Berührung des Buttons nicht eingeblendet.

Progressive Enhancement: die responsive Navigation verbessern

Mit einer leicht anderen Herangehensweise funktioniert diese Navigation immer, auch ohne JavaScript:

  1. Ohne JavaScript …
    • wird die Navigationsliste offen angezeigt und der Menübutton versteckt.
    • können Besucher mit der Navigation von einer Seite zur anderen navigieren.
  2. Mit JavaScript …
    • wird der Menübutton sichtbar und die Navigationsliste ausgeblendet.
    • wird die Navigationsliste nach Antippen des Menübuttons sanft eingeblendet.

Dieses Designprinzip heißt Progressive Enhancement, was man mit schrittweise Verbesserung übersetzen könnte: Ohne JavaScript funktioniert alles, mit JavaScript wird es benutzerfreundlicher.

Der folgende CodePen zeigt die Navigation am Ende dieses Beitrags.

See the Pen Einstieg in HTML und CSS: responsive Navigation mit »progressive enhancement« by Peter Müller (@pmmueller) on CodePen.

Schritt 1: So stellen Sie fest, ob JavaScript im Browser aktiviert ist.

Im ersten Schritt prüfen Sie, ob JavaScript im Browser des Besuchers aktiviert ist:

  • Im HTML geben Sie dem Stammelement html eine Klasse wie z. B. no-js.
  • Diese Klasse wird anschließend per JavaScript geändert und heißt dann zum Beispiel js.

Das Stammelement bekommt also zunächst einmal die Klasse no-js:

<!-- Das Stammelement bekommt die Klasse no-js -->
<html lang="de" class="no-js">

Im <head> der Seite folgen dann in einem <script>-Element zwei JavaScript-Anweisungen:

<!-- JavaScript entfernt die Klasse no-js und fügt js hinzu --> 
<script>
  document.documentElement.classList.remove('no-js');
  document.documentElement.classList.add('js');
</script>

Ohne JavaScript werden diese Anweisungen ignoriert und das Stammelement behält die Klasse no-js. Mit JavaScript wird die Klasse no-js entfernt und durch die Klasse js ersetzt:

  • document.documentElement ermittelt das Stammelement des Dokumentes, also html.
  • classList.remove('no-js') entfernt die Klasse no-js vom Stammelement html.
  • classList.add('js') fügt dem Stammelement die Klasse js hinzu.

In einem Browser mit JavaScript sieht das Stammelement nach diesen Anweisungen also wie folgt aus:

<!-- Mit JavaScript hat das Stammelement die Klasse js -->
<html lang="de" class="js">

Im CSS zur Gestaltung der Navigation nutzen Sie die Klassen no-js und js als Selektoren.

Testen: JavaScript im Browser an- und ausschalten

Zum Testen können Sie mit der Web Developer Toolbar in Chrome und Firefox JavaScript sehr einfach an- und ausschalten: Web Developer > Disable > Disable JavaScript, und dann die Seite neu laden.

Schritt 2: »Mobile First« – die grundlegende Gestaltung

Getreu dem Motto Mobile First bekommt die Navigation zunächst eine grundlegende Gestaltung für schmale Viewports. Die Navigationsliste wird dabei zur Flexbox, in der die Listenelemente untereinander stehen. Die eigentliche Gestaltung bekommen die Hyperlinks in den Listenelementen.

/** 
  * Mobile first - die grundlegende Gestaltung der Navigation 
  */
 
.site-nav {
  position: static; 
  padding: 0; 
}

.site-nav ul { 
  display: flex; 
  flex-flow: column; 
  list-style: none; 
  padding: 0; 
  margin: 0; 
}

.site-nav a {
  display: block;
  text-decoration: none; 
  background: #333; 
  color: white; 
  padding: 0.5rem 1rem;
  margin-right: -1rem; 
  margin-left: -1rem; 
}

.site-nav a:hover, 
.site-nav a:focus { 
  background: #0b74b8; 
  color: white;   
}

.site-nav .current a { 
  background: #666; 
  color: white; 
}

Schritt 3: Kein JavaScript? Menübutton ausblenden.

Ohne JavaScript hat der Menübutton keinerlei Nutzen, und daher können Sie ihn im Stylesheet mit der Klasse no-js ausblenden:

/** 
  * Kein JavaScript? Menübutton ausblenden 
  */

.no-js .menubutton { 
  display: none; 
}

In einem Browser ohne JavaScript sieht die Navigation dann so aus wie in der folgenden Abbildung. Der Menübutton wird ausgeblendet, die Navigationsliste hingegen ist in voller Länge zu sehen und für Besucher nutzbar.

Die Navigation in einem schmalen Viewport ohne JavaScript

Schritt 4: JavaScript aktiv? Menübutton und Navigationsliste gestalten

Die Gestaltung des Menübuttons und das Aus- und Einblenden der Navigation erfolgt mit der Klasse js, die es wie weiter oben gezeigt nur gibt, wenn JavaScript im Browser aktiviert ist.

1. Den Menübutton gestalten

Die Selektoren der beiden CSS-Regeln zur Gestaltung des Menübuttons beginnen mit der Klasse .js.

/** 
  * JavaScript aktiv? 
  * 1. Menübutton gestalten 
  */

.js .menubutton { 
  display: flex; 
  align-items: center; 
  cursor: pointer; 
  font: inherit; 
  text-align: center; 
  background: inherit; 
  color: white; 
  padding: 0.5rem 0rem; 
  border: 0; 
  margin: 0; 
}

.js .menubutton::before {
  content: url(../bilder/menuburger.svg); 
  width: 1rem; 
  height: 1rem; 
  margin-right: 0.25rem; 
}

2. Die Navigationsliste ausblenden

Wenn JavaScript aktiviert ist, wird die Navigationsliste ausgeblendet.

/**
  * 2. Navigationsliste ausblenden 
  */

.js .site-nav ul {
  max-height: 0; 
  overflow: hidden; 
  padding: 0; 
} 

3. Bei Antippen oder Anklicken des Menübuttons die Navigationsliste einblenden

Ein Antippen oder Anklicken des Menübuttons fügt im Quelltext die Klasse showmenu hinzu. Die folgenden Selektoren funktionieren also nur, wenn JavaScript aktiv ist (.js) und der Menübutton berührt wurde (.showmenu).

/** 
  * 3. Bei Berührung des Menübuttons die Navigationsliste einblenden 
  */

.js .menubutton.showmenu + ul {
  max-height: 100rem; 
  transition: max-height 500ms; 
}

.js .menubutton.showmenu::before { 
  content: url(../bilder/menuclose.svg); 
}

Auf mobilen Geräten funktioniert die Navigation damit wie folgt:

  1. Nach dem Laden der Seite wird der Menübutton mit einem Hamburger-Symbol angezeigt.
  2. Nach einem Klick auf den Menübutton wird die Navigationsliste angezeigt und das Symbol geändert.

Das folgende zwei Sekunden kurze Video zeigt diesen Vorgang in Aktion.

Das Video zeigt die Navigation in einem schmalen Viewport mit JavaScript

Schritt 5: Viewport breiter als 600px? Horizontale Navigation.

Mit der folgenden Media Query wird die Navigation ab einer Viewportbreite von 600px horizontal dargestellt. Dabei spielt es keine Rolle, ob JavaScript aktiviert ist oder nicht.

/** 
   * Viewport breiter als 600px? 
   * Navigation horizontal darstellen 
   */ 

@media screen and (min-width: 600px) {

  .menubutton { display: none !important; } 
  
  .site-nav { position: sticky; }
  
  .site-nav ul { 
    max-height: none !important; 
    flex-flow: row; 
    padding: 0; 
  }

  .site-nav li {
    flex: 1; 
    max-width: 10rem; 
    text-align: center; 
    border-left: 1px solid #eee; 
    margin: 0; 
  }

  .site-nav li:first-child { 
    margin: 0; 
  }

  .site-nav li:last-child {
    border-right: 1px solid #eee; 
    margin: 0; 
  }

  .site-nav a {
    margin-right: 0; 
    margin-left: 0; 
  }

}  /* Ende @media */ 

Horizontal sieht die Navigation im Browser mit dieser Gestaltung so aus:

Responsive Navigation für die Übungswebsite - horizontal
Die horizontale Navigation in einem breiten Viewport (ab 600px)

Falls Ihnen dieser Beitrag gefällt, können Sie ihn weiterempfehlen:

Schreibe einen Kommentar