Menu responsive con Flexbox: creare il menu e i sottomenu

Menu responsive con Flexbox: creare il menu e i sottomenu

Il posizionamento degli elementi è sempre stato un problema vero, anche con sistemi come block, inline-block o table. Che si usino i float o gli inline-block, non è raro incontrare complicazioni in questo campo. Per fortuna le cose si sono mosse e oggi, con l’abbandono progressivo dei browser datati come Internet Explorer, possiamo iniziare ad allineare i nostri elementi con il modulo Flexbox. In questo tutorial ti mostro quanto è facile costruire un menu in poche righe.

Passo 1 – Le basi

Prima di scrivere CSS, definiamo la base del nostro menu in HTML5.

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>

Applichiamo uno stile di base al menu:

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

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

Passo 2 – Il menu

Una volta poste le basi dei nostri elementi, possiamo passare al menu vero e proprio!

css
.nav .menu {
    display: flex; /*1*/
    flex-direction : row; /*2*/
    justify-content: center; /*3*/
}
  • 1 – Impostiamo la visualizzazione in modalità flexbox.
  • 2 – Con flex-direction chiediamo che i figli dell’elemento corrente siano allineati in riga.
  • 3 – justify-content permette di allineare i figli a sinistra, al centro o a destra dell’elemento corrente.

flexbox01.JPG

In sole 3 righe hai già l’inizio di un menu. Se ti serve allinearlo a destra, basta mettere flex-end sulla proprietà justify-content. Vuoi invertire la riga? Metti row-reverse su flex-direction. Flexbox non è solo più semplice: è anche molto flessibile. E se ti dicessi che la versione mobile occupa una riga sola?

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

@media(max-width: 450px) {
      flex-flow: column wrap; /*4*/
    }
}
  • 4 – Su una risoluzione di tipo mobile, con flex-flow, che è la scorciatoia di flex-direction e flex-wrap, mostriamo i figli in colonna e permettiamo l’andata a capo.

flexbox02.JPG

Ed ecco fatto. D’accordo, in realtà sono 3, ma se ci fermiamo qui abbiamo già una prima versione base del nostro menu responsive. Lo sai bene però: ci sono anche i sottomenu, ed è proprio quello che vedremo nel passo successivo!

See the Pen Menu responsive avec Flexbox – 1 by Damien Flandrin (@dam62500) on CodePen.

Passo 3 – I sottomenu

Per costruire un sottomenu creiamo due classi: has-children, che si applica a un elemento del menu con un sottomenu, e la classe 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 -->

Nel mio esempio ho deciso di mettere un sottomenu dentro un sottomenu (inception!), perché non è raro imbattersi in casi del genere.

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 – Posizioniamo l’elemento in relativo, così da poter allineare il sottomenu rispetto al suo genitore.
  • 2 – Se il cursore del mouse è su un elemento che contiene un sottomenu, mostriamo il sottomenu in modalità flexbox.
  • 3 – Definiamo il comportamento predefinito del sottomenu: di partenza deve restare nascosto, si allinea in colonna e gli diamo una dimensione minima di 100 px (non è obbligatorio, ma nel mio esempio il sottomenu risulterebbe ridicolmente piccolo).
  • 4 – Allineiamo il testo a sinistra per una questione estetica.
  • 5 – Allineiamo il sotto-sottomenu alla stessa altezza del genitore e alla sua destra (right: 0 px; non funzionerebbe in un caso del genere).

flexbox03.JPG

E ora la versione responsive:

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

Per le interazioni con gli utenti su mobile e tablet affidati al JavaScript. E se hai dei sottomenu, aggiungerei anche un menu a scomparsa laterale: nel mio tutorial non l’ho fatto, ma per i tuoi visitatori è molto più comodo.

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 Menu responsive avec Flexbox – 2 by Damien Flandrin (@dam62500) on CodePen.

Compatibilità di Flexbox

Flexbox è piuttosto ben supportato dai browser, ma ci sono comunque alcuni dettagli da conoscere per curarne bene il supporto. Oggi si può iniziare a prendere in considerazione il suo uso e non c’è dubbio che fra qualche anno lo vedremo diffondersi molto, anche nei framework più noti come Bootstrap o Foundation.

Internet Explorer Firefox Chrome Safari Android
Supportato da Internet Explorer 10 con il prefisso -ms-, senza prefisso oltre la 10. Da Firefox 19 a 21 usa il prefisso -moz-, senza prefisso oltre la 21 Fino alla versione 28 con -webkit-, senza prefisso oltre la 28 Fino alla 10 con -webkit-, senza prefisso oltre Con -webkit- fino alla versione 4.3, senza prefisso oltre

CSS

Damien Flandrin Sviluppatore web dal 2010, creatore di Gekkode e di Email Impact. Ogni articolo è testato su un progetto reale prima della pubblicazione. Contatti
Newsletter

I nuovi test, tutorial e progetti, via e-mail.

Test riproducibili, codice versionato, risultati datati. Mai spam.