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>☰</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.
Schon interessant was man so alles mit fem Checkboxhack machrn kann. Allerdings würde ich gerne das Ganze mal auf Barrierefreiheit untersuchen. Man kann ja keine aria labels setzen.
Von daher sollte man vielleicht doch einfach JS für Funktionalitäten nutzen, so wir vom W3C gedacht.
hi,
sollten die aria-labels erst in der mobilen navigation verzeichnet werden?
aria-haspopup=“true“ könnte in den schon stehen, gleich ob mobile oder desktop version.
oder irre ich?
viele grüße!
karsten
Hallo zusammen,
ich finde die Idee einer responsiven CSS-Navi prima und hab mir die Check-Box Hack Anweisung für meine Navi angepasst. Leider gibtes dabei ein Problem, dass ich nicht gelöst kriege und dass dazu führt, dass ich die Navi so nicht benutzen kann. Wenn ich die Anzeige mittels der Verschiebung (-9999px) unsichtbar mache, nimmt es mir rechnersich trotzdem den benötigten Platz unter dem Menübutton weg, sodass sich der nachfolgende Inhalt auch dann nach unten schiebt, wenn das Menü selbsdt nicht sichtbar ist. Es klafft eine größe Lücke zwischen Menübutton und Inhalt, die sich erst schließt, wenn mit einem Klick auf den Menübutton das Menü sichtbar wird und diese Lücke dann schließt. Das ist schlecht, denn wenn ich 6 Menüpunkte habe, bleibt auf dem Handy unter dem Menübutton nur ein leeres Feld sichtbar. Sowohl praktisch wie optisch nicht einsatzbar. Ich habe die Positionsangaben mittels Pixel dann versuchsweise ersetzt durch (Display: none bzw. Display: yes. Damit klappt es, dass meine Inhalte bei (noch) zugeklappter Navi wieder hochrutschen bis unter den Menübutton, aber die Navi lässt sich nun nicht mehr aufklappen, auch wenn ich für die Anweisung nach dem Check ausdrücklcih die Anzeige mit display: yes beschrieben habe. Gibt es dafür eine Lösung?Das wäre schön, denn ich würde die NAvi wirklich gern einsetzen. Danke und LG Doris
Ich bin so doof…
Bei Abschicken des letzten Posts kam mir die Idee und ich hab mal das display: yes durch display:block ersetzt…
Nu geht es :-)
Hallo Doris,
schön, dass es nun funktioniert.
Liebe Grüße
Olli
Im Prinzip schön und vielen Dank dafür.
Praktisch funktioniert es im Android-Browser (Android 4.4.2, HTC One 2 Mini) nicht.
Das vergleichbare Menü auf dieser Seite funktioniert allerdings, es muss also irgendeine Kleinigkeit sein.
Ich habe auch mal nur eine schlichte Seite nur mit deinem Code erstellt. Auch da „klappt“ nichts.
Hast Du einen Tipp?
Gruß und Dank,
Andreas.
Mit der Ergänzung „Fix for Android“ aus https://css-tricks.com/responsive-menu-concepts/ funktioniert’s.
Danke für den Hinweis, Andreas.
Gruß Olli
[…] […]
Hi Olli,
Danke für dieses Tutorial. Ich habe das ganze soweit erstellt, leider öffnet sich das Drop-Down Menü nicht auf jedem Handy oder Ipad. Ich konnte den Fehler bisher nicht finden. Komisch ist auch, dass bei zwei den gleichen Handys, es auf einem funktioniert und auf dem anderen nicht. Handyeinstellungen wurden auch schon zurückgesetzt.
Vielleicht hast du ja eine Idee!
Danke und LG
Maren
Hallo,
zu aller Erst herzlichen Dank für dieses klasse Beispiel eines CSS-Menüs!
Was mir aufgefallen ist:
Die kleinen Pfeilchen neben den „aufklappbaren“ Navigationspunkten werden – soweit ich das testen konnte – in allen gängigen Browsern richtig positioniert. Nur im Internet Explorer nicht. In diesem hängen die Pfeilchen rechtsbündig unter dem letzten Buchstaben des Textes.
Die Pfeilchen im Untermenü – also sprich die, die in der 2. Ebene den Hinweis auf die 3. Ebene geben – werden komischerweise auch im Internet Explorer richtig positioniert.
Hat jemand eine Idee, wie man diese in der ersten Ebene auch im Internet Explorer an die richtige Stelle – also sprich rechts neben den Text – positionieren kann?
Hallo Christian,
das Problem hatten wir schon einmal (s. hier). An deiner Stelle würde ich mir keinen Kopf mehr bezüglich Fehldarstellungen des Internet Explorers machen. Ist eine schnell aussterbende Spezies.
Gruß Olli
Hallo Olli,
erstmal sorry, dass ich mich erst jetzt melde. Bin leider die ganze Zeit nicht dazu gekommen…
Vielen Dank für deinen Tipp. Mit der Positionierung „absolute“ statt „relative“ klappt es auch im IE super.
Ich wünschte der IE wäre wirklich eine schnell aussterbende Spezies. Leider kommen auf unsere Seite immernoch mehr als die Hälfte der Besucher mit dem IE und da wollte ich auch in diesem Browser eine perfekte Darstellung.
Dieses Tutorial ist insoweit ganz gut zu gebrauchen, solange man nicht auf einem mobilen Gerät surft! Und „responsiv“ bedeutet für mich, dass man die Desktopvariante auf einem Smartphone oder Touchlet sich anschauen kann.
Aber dann fehlt ein entscheidendes Detail: –> dass das Menü auf einem mobilen Gerät nicht wieder sofort zugeht …. richtig? Was nützen einem dann die Untermnüs, wenn man nicht rankommt. Ergo – einfach mal hier nachlesen (http://osvaldas.info/drop-down-navigation-responsive-and-touch-friendly) und das kleine Script an entsprechender Stelle nachreichen und schon klappt aus mit der schönen Nachbarin!
Hi, vielen Dank für das super Tutorial. Eine Frage bleibt mir aber noch. Wie schaffe ich es die Unterpunkte auch klappbar zu machen?
Hey hey! Vielen Dank für das Menü. Seit der Umstellung meiner Seite auf SSL bockt JS. Aber das ist ein anderes Thema. Auffällig ist: Safari zeigt alles entsprechend an, nur klappt das Menü, nachdem es auf dem iPhone aufgeklappt war, nicht wieder ein. – Was kann man tun?
Danke für das Tutorial….bisher geht alles recht gut, aber auf Android-Handies wird das Burger-Symbol nicht dargestellt. Hat jemand einen Tipp wie man das in den Griff bekommt ?
Moin !
[quote]
Aber dann fehlt ein entscheidendes Detail: –> dass das Menü auf einem mobilen Gerät nicht wieder sofort zugeht …. richtig? Was nützen einem dann die Untermnüs, wenn man nicht rankommt. Ergo – einfach mal hier nachlesen (http://osvaldas.info/drop-down-navigation-responsive-and-touch-friendly) und das kleine Script an entsprechender Stelle nachreichen und schon klappt aus mit der schönen Nachbarin!
[/Quote]
Hab Probleme auf dem iPad mit dem Originalscript. Dawerden die UnterMenüs einfach nicht angezeit in der Normalansicht. Dir das Responsive Menü geht. Wo wird denn die Erweiterung eingebaut ? Ich bekomme es einfach nicht hin.
Hallo Olli,
ich bin beim Finden einer Lösung hier bei dir gelandet und finde die Beiträge sehr interessant. Ich habe das Hamburger-Menü erfolgreich in meine Webseite http://www.jutta-weiland.de eingebaut. Folgende Problematik tritt auf: ich habe im Menü Individuelle Links als Sprungmarken verlinkt und wenn ich die Punkte auswähle, sehe ich dass ich an die richtige Stelle geleitet werde. Das Menü muss ich jedoch manuell schließen um den kompletten Inhalt sehen zu können. Evtl. hast du ja eine Idee. LG Joachim
der Viewport fehlt ;)
hi,
sehr geiler Beitrag. Wird ich ausprobieren. Weiter so!
hallo olli,
ein großes danke für deinen beitrag. deine navigationslösung ist sauber, elegant und trotzdem vom code her sehr überschaubar und klar!
was es für mich jetzt noch perfekt machen würde, wäre, dass bei der mobilen version nicht gleich alle untermenüpunkte auf einmal ausklappen, sondern erst, wenn man auf einen hauptmenüpunkt klickt. da ich in erster linie ein grafiker und kein programmierer bin, frag ich dich, ob du lust hast hier ein update vorzunehmen. gern spende ich auch was dafür. denn du hast hier wirklich einen guten beitrag geleistet! gerade für solche wie mich ;-)
Bobo und noch jemand bemängelten, dass Desktopmenue sei nicht touch-friendly.
Ich dachte das auch erst, bis ich merkte, nach dem Listtag submenu keinen Link einsetzen zu dürfen, so wie ich es bei den anderen Listelementen gemacht habe.
Falsch:
Obst
Richtig:
Obst
Man wird schnell verleitet auch im Parrent die Raute mit einem Link zu ersetzen und dann geht das Menue auf einem Touchscreen logischerweise wieder zu, weil dann ja der Link geöffnet wird.
Allerdings muss man dazu anmerken, dass durch das auslassen des Links im Parrent, die Bedienung im Smartphone Menü, nicht mehr intuitiv wirkt, weil bei touch auf das Submenue nichts passiert.
Einen Tod muss man immer sterben, bei jedem Design.
Ich finde das Menue echt Klasse, weil übersichtlich und funktionell.
Vielen Dank
Oliver
Hallo Oliver,
vielen Dank für das tolle Tutorial. Die Lösung finde ich sehr schön, da sie relativ wenig code benötigt und trotzdem schick und leicht anpassbar ist. Ich habe beim Nach- und Umbauen viel gelernt.
Wie einige meiner Vorredner hätte ich aber auch gerne, dass die Menüs auch auf kleinen Displays klappbar sind. Habe soweit auch alles hinbekommen, nur wenn ich die Untermenüs einfliegen lasse machen die anderen Menüpunkte keinen Platz…
Kannst Du evtl. eine Lösung anbieten?
Außerdem habe ich noch eine andere Frage. Um Sachen aus dem Blick zu räumen schiebst Du -9999 nach links UND oben. Warum?
LG ogli
Moin Olli, ich habe mir vor paar jahren glaub ich genau diesen code für ein responsives mobile menu von deiner seite kopiert. Funktioniert 1 a danke dafür auf jedenfall. Jetzt mein Frage punkt. Ich hab im Menu einige Rubriken auf der Seite über „ “ wie es in deinem Code drin ist. Problem was ich hab: ich möchte das sich das Menu nach klick auf so einen link automatisiert schließt am besten über Js oder wenns geht (bevorzugt) CSS ;) damit der Nutzer wieder voll den Durchblick auf der Seite hat. Kannst du mir da helfen.
Gruß Felix
Hallo Olli! Ich danke Dir für Deine Seite(n) und die viele Arbeit, die Du da ganz offensichtlich investiert hast. Speziell dieses responsive Dropdown-Menü fand ich so inspirierend, dass ich es gleich mal nachbauen musste (siehe Link) – ist das in Ordnung für Dich? Schöne Grüße, Rüdiger