Horizontales Menü mit Trennern

Autor: Aykut Şensoy, Datum:

Ein horizontales Menü mit Trennern begegnet uns häufig im Footer einer Webseite. Oft sind es mehrzeilige Menüpunkte, die durch einen Punkt oder Strich getrennt sind. Das Problem dabei ist, dass man zwar in den einzelnen Zeilen zwischen den Menüpunkten den Trenner gerne haben möchte, aber nicht am Anfang oder Ende der jeweiligen Zeile. Ich selbst dachte lange Zeit, dass es mit CSS alleine nicht geht. Es schien eine große Herausforderung zu sein, wo in der Vergangenheit auch JavaScript-Lösungen herhalten mussten.

Da für unseren Mandanten eine Neugestaltung der Hauptnavigtion ansteht und wir diese Anforderung für die Submenü-Punkte brauchen, habe ich mich erneut an dieses Thema gesetzt, recherchiert und eine simple CSS-Lösung gefunden. Sie ist konform zu den Webstandards, d.h. sie kommt ganz ohne Hacks aus.

Wir definieren zuerst das grundlegende HTML-Markup für unsere Menü-Liste nach folgendem Muster.

<ul>
  <li>Impressum</li>
  <li>Hilfe</li>
  <li>Kontakt</li>
	...
</ul>

Wir schauen uns erst einmal folgendes Beispiel an. Ich nutze einen simplen Punkt als Trenner. Die nachfolgende CSS ist die übliche Weise wie Trenner zwischen den Elementen definiert werden. In diesem Fall wird hier ::after benutzt. Man sieht im HTML, dass immer am Ende der jeweiligen Zeile der unerwünschte Trenner zu sehen ist. Wenn wir ::before nutzen würden, hätten wir das gleiche Problem nur umgekehrt. Der Trenner wäre immer am Anfang der jeweiligen Zeile.
Das ist aber nicht das einzige Problem. Zu beachten ist auch das Leerzeichen vor dem Trenner in der content Property als Ausgleich für das Leerzeichen zwischen den Listen-Elementen. Sonst würden die Trenner nicht mittig positioniert werden. Denn die li-Tags erzeugen immer ein Leerzeichen, wenn sie untereinander im Quellcode definiert werden und nicht direkt aneinander kleben. D.h. ich könnte das Leerzeichen weglassen, wenn die li-Tags lückenlos direkt nebeineinander definiert wären. Dann wird es aber im Quellcode sehr unleserlich und die Linter spielen da auch nicht ohne Weiteres mit.

ul {
  text-align: center;
}

ul li {
  display: inline;
}

ul li::after {
  content:" •";
}
  • Impressum
  • Hilfe
  • Kontakt
  • Media
  • Jobs
  • Presse
  • Datenschutz
  • Privatsphäre
  • Nutzungsbedingungen
  • Archiv
  • Newsletter
  • FAQ

Als Nächstes schauen wir uns die Lösung an, die das gewünschte Ergebnis erzeugt. Zur Lösung dieses Problems wird eine besondere Eigenart der Browser ausgenutzt. Wenn nämlich im Browser inline-Elemente automatisch umbrechen, kollabieren die Leerzeichen am Ende der Zeile. Das muss auch so sein, sonst würde ja immer am Anfang der Zeile der Text mit einem Leerzeichen eingerückt sein. Diese Eigenschaft der Browser machen wir uns nun zu Nutze. Dafür muss man nur die Art, wie man das Pseudo-Element ::after definiert, etwas umschreiben. Anstatt in der content-Property den Trenner zu definieren, definiert man hier nur ein Leerzeichen. Der Trenner wird dann als background-image zugewiesen. In diesem Fall als inline SVG.
Auch das andere Problem mit der mittigen Positionierung wird mit dieser Lösung behoben. Es ist nicht mehr relevant, ob die li-Tags untereinander oder direkt nebeneinder im Quellcode stehen. Ich habe hier im Beispiel noch zusätzlich die Property letter-spacing hinzugefügt. Mit dem letter-spacing kann man sehr gut die Abstände zwischen den einzelnen Listen-Elementen steuern.

ul li::after {
  content:" ";
  letter-spacing: 24px;
  background: url('data:image/svg+xml;utf8,<svg width="6" height="6" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" r="6" /></svg>') center center no-repeat;
}
  • Impressum
  • Hilfe
  • Kontakt
  • Media
  • Jobs
  • Presse
  • Datenschutz
  • Privatsphäre
  • Nutzungsbedingungen
  • Archiv
  • Newsletter
  • FAQ

Sie können die Lösung testen, in dem Sie die rechte untere Ecke des Containers mit der Menü-Liste greifen und kleiner ziehen (außer auf iOS-Geräten, da CSS resize aktuell noch nicht unterstützt wird). Egal wie oft die Listen-ELemente umbrechen, am Ende der jeweiligen Zeilen ist niemals ein Trenner zu sehen, da das Leerzeichen, welches vom ::after erzeugt wurde, jedesmal beim automatischen Umbrechen kollabiert.