Responsives Menü mit Flexbox bauen, samt Untermenüs

Elemente zu positionieren war immer ein Ärgernis, egal ob mit Floats oder mit inline-block. Flexbox räumt damit auf: drei CSS-Zeilen für eine waagerechte Navigationsleiste, eine weitere für das mobile Layout und ein paar Regeln für Untermenüs beim Hover. Hier ist das Ganze, Schritt für Schritt.

Responsives Menü mit Flexbox bauen, samt Untermenüs

Elemente zu positionieren war lange ein echtes Ärgernis, trotz aller Verfahren wie block, inline-block oder table und egal ob mit Floats oder mit inline-block. Probleme in diesem Bereich waren eher die Regel als die Ausnahme. Inzwischen hat sich einiges getan, und weil alte Browser wie Internet Explorer nach und nach verschwinden, können wir unsere Elemente endlich mit dem Flexbox-Modul ausrichten. In diesem Tutorial zeige ich dir, wie leicht sich damit ein Menü in wenigen Zeilen bauen lässt.

Schritt 1 – die Grundlage

Bevor wir uns ans CSS setzen, legen wir die Grundlage unseres Menüs in HTML5 fest.

html
<nav class="nav" role="navigation">
    <ul clas="menu">
        <li><a href="https://www.damienflandrin.fr/blog/post/#">Accueil</a></li>
        <li><a href="https://www.damienflandrin.fr/blog/post/#">Catégories</a></li>
        <li><a href="https://www.damienflandrin.fr/blog/post/#">À Propos de Moi</a></li>
        <li><a href="https://www.damienflandrin.fr/blog/post/#">Contact</a></li>
    </ul>
</nav>

Dann geben wir dem Menü ein paar grundlegende Styles:

css
.nav ul {
    margin: 0px;
    padding: 0px;
    background: tomato;
    list-style:none;
}

.nav a {
    padding: 1em;
    display: block;
    text-align:center;
    text-decoration: none;
}

Schritt 2 – das Menü

Die Grundlagen stehen, jetzt geht es an das Menü selbst.

css
.nav .menu {
    display: flex; /*1*/
    flex-direction : row; /*2*/
    justify-content: center; /*3*/
}
  • 1 – Wir stellen die Anzeige auf Flexbox um.
  • 2 – Mit flex-direction sollen die Kinder des aktuellen Elements in einer Zeile liegen.
  • 3 – Mit justify-content richten wir die Kinder links, mittig oder rechts im aktuellen Element aus.

flexbox01.JPG

Mit gerade einmal drei Zeilen hast du den Anfang eines Menüs. Soll es rechts stehen, setzt du einfach flex-end für das Attribut justify-content. Du willst die Zeile umdrehen? Dann row-reverse für flex-direction. Flexbox ist nicht nur einfacher, sondern auch sehr flexibel. Und die mobile Fassung? Die kostet eine einzige Zeile.

css
.nav .menu {
    display: flex; /*1*/
    flex-direction : row; /*2*/
    justify-content: center; /*3*/

@media(max-width: 450px) {
      flex-flow: column wrap; /*4*/
    }
}
  • 4 – Sobald wir bei einer mobilen Auflösung sind, zeigen wir die Kinder mit flex-flow, der Kurzschreibweise aus flex-direction und flex-wrap, als Spalte an und erlauben den Umbruch.

flexbox02.JPG

Und fertig. Gut, genau genommen sind es drei Zeilen, aber egal: Damit steht eine erste, einfache Fassung unseres responsiven Menüs. Es fehlen natürlich noch die Untermenüs, und genau darum geht es im nächsten Schritt.

See the Pen Responsives Menü mit Flexbox – 1 by Damien Flandrin (@dam62500) on CodePen.

Schritt 3 – die Untermenüs

Für ein Untermenü legen wir zwei Klassen an: has-children für jeden Menüpunkt, der ein Untermenü besitzt, und die Klasse sous-menu.

html
<!-- notre menu flexbox -->
    <nav class="nav" role="navigation">
        <ul class="menu">
            <li><a href="https://www.damienflandrin.fr/blog/post/#">Accueil</a></li>
            <li class="has-children"><a href="https://www.damienflandrin.fr/blog/post/#">Catégories</a>
                <!-- sous menu-->
                <ul class="sous-menu">
                    <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 1</a></li>
                    <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 2</a></li>
                    <li class="has-children"><a href="https://www.damienflandrin.fr/blog/post/#">Item 3</a>
                        <!-- un sous menu dans un sous-menu-->
                        <ul class="sous-menu">
                            <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 1</a></li>
                            <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 2</a></li>
                            <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 3</a></li>
                            <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 4</a></li>
                        </ul>
                        <!-- /un sous menu dans un sous-menu-->
                    </li>
                    <li><a href="https://www.damienflandrin.fr/blog/post/#">Item 4</a></li>
                </ul>
                <!-- /sous menu-->
            </li>
            <li><a href="https://www.damienflandrin.fr/blog/post/#">À Propos de Moi</a></li>
            <li><a href="https://www.damienflandrin.fr/blog/post/#">Contact</a></li>
        </ul>
    </nav>
<!-- /notre menu flexbox -->

In meinem Beispiel habe ich ein Untermenü in ein Untermenü gesteckt (Inception!), ein Fall, der in der Praxis durchaus regelmäßig vorkommt.

css
  .has-children { /*1*/
    position: relative;
  }

.has-children:hover > .sous-menu { /*2*/
    display: flex;
  }

.sous-menu { /*3*/
    display: none;
    flex-flow: column wrap;
    min-width: 100px;
    position: absolute;
    background: dodgerblue;
  }

.sous-menu a { /*4*/
    text-align: left;
    color:white;
  }

.sous-menu .sous-menu { /*5*/
    top: 0px;
    left: 100%;
    background: #1e76d6;
  }
  • 1 – Wir positionieren das Element relativ, damit sich das Untermenü an seinem Elternelement ausrichten lässt.
  • 2 – Steht der Mauszeiger auf einem Element mit Untermenü, zeigen wir dieses Untermenü als Flexbox an.
  • 3 – Wir legen das Standardverhalten des Untermenüs fest: Zunächst ist es versteckt, es wird als Spalte ausgerichtet und bekommt eine Mindestbreite von 100 px (nicht zwingend, aber in meinem Beispiel wäre das Untermenü sonst lächerlich schmal).
  • 4 – Den Text richten wir aus optischen Gründen links aus.
  • 5 – Das Unter-Untermenü setzen wir auf dieselbe Höhe wie sein Elternelement und rechts daneben (right: 0 px; würde in einem solchen Fall nicht funktionieren).

flexbox03.JPG

Und die responsive Variante:

css
.sous-menu {
    display: none;
    flex-flow: column wrap;
    min-width: 100px;
    position: absolute;
    background: dodgerblue;
    @media(max-width: 450px) {
      position: static;
    }
}

.sous-menu.is-active {
        display: flex!important;
}

.sous-menu a { /*4*/
    text-align: left;
        @media(max-width: 450px) {
      text-align: center;
    }
    color:white;
  }

.sous-menu .sous-menu {
    top: 0px;
    left: 100%;
    background: #1e76d6;
}

flexbox04.JPG

Setz für die Interaktion mit Nutzern auf Smartphone und Tablet lieber auf JavaScript. Und wenn du Untermenüs hast, bau das Menü als Slide-in. In meinem Tutorial habe ich das nicht gemacht, für deine Besucher ist es aber deutlich angenehmer zu bedienen.

javascript
$('.sous-menu').click(function(){
    if ($(window).width() < 450) {
        if($(this).hasClass('is-active'))
            $(this).removeClass('is-active');
        else
            $(this).addClass('is-active');
    }
});

See the Pen Responsives Menü mit Flexbox – 2 by Damien Flandrin (@dam62500) on CodePen.

Browser-Support von Flexbox

Flexbox wird von den Browsern recht gut unterstützt, ein paar Kleinigkeiten muss man aber kennen, um den Support sauber abzudecken. Heute lässt sich der Einsatz von Flexbox ernsthaft in Betracht ziehen, und in ein paar Jahren wird seine Verbreitung zweifellos stark zunehmen, auch in den bekanntesten Frameworks wie Bootstrap oder Foundation.

Internet Explorer Firefox Chrome Safari Android
Unterstützt ab Internet Explorer 10 mit dem Präfix -ms-, oberhalb von 10 ohne Präfix. Firefox 19 bis 21 mit dem Präfix -moz-, oberhalb von 21 ohne Präfix Bis Version 28 mit -webkit-, oberhalb von 28 ohne Präfix Bis Version 10 mit -webkit-, darüber ohne Präfix Mit -webkit- bis Version 4.3, darüber ohne Präfix

CSS

Damien Flandrin Webentwickler seit 2010, Gründer von Gekkode und Email Impact. Jeder Artikel wird vor der Veröffentlichung an einem echten Projekt getestet. Kontakt
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.