In un recente articolo abbiamo visto come convertire un menù in una tendina per renderlo responsive. Sebbene sia una pratica molto diffusa ed utilizzata, mi sono accorto che non è ben supportata da tutti i browser mobile, a causa dell’operazione che si fa in Javascript di intercettare il cambio di url al cambio di opzione della select (al momento in cui parlo su Firefox per mobile non funziona).

Vediamo oggi quindi una soluzione applicabile a menù abbastanza semplici graficamente che permette di “ri-impilare” le voci di menù, in modo responsive, a seconda della dimensione dello schermo del dispositivo.

Demo menù responsive

HTML: un semplice menù a tendina

<nav>
	<ul class="clearfix">
		<li><a href="#">Home</a></li>
		<li><a href="#">Chi Siamo</a></li>
		<li><a href="#">Dove Siamo</a></li>
		<li><a href="#">Contatti</a></li>
	</ul>
	<a href="javascript:void(0);" id="pull">Menu</a>
</nav>

La struttura html è semplicissima, premetto che per utilizzare il sistema che stiamo vedendo con menù di sottolivello ci si dovrà ingegnare per gestire al meglio le aperture e chiusure. Infine anticipo che, per gli amanti della semantica, è possibile usare al posto del link con id “pull” un qualsiasi altro elemento del DOM.

PS: non dimenticate di inserire il meta viewport.

CSS: menù e media queries

*,
*:after,
*:before {
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	box-sizing: border-box;
	padding: 0;
	margin: 0;
}
/* Clearfix Solo IE8 e superiori */
.clearfix:after {
  content: "";
  display: table;
  clear: both;
}
/* Basic */
body {
	background: #fff;
}
nav {
	background: #3B3B3B;
	font-size: 0; /* Hackfix per rimuovere spazio tra elementi inline-block */
	font-family: Arial, sans-serif;
	font-weight: bold;
	border-bottom: 2px solid #EF580D;
}
nav ul {
	margin: 0 auto;
	width: 960px;
	text-align:center;
}
nav li {
	display:inline-block;
}
nav a {
	font-size: 14px;
	padding:20px 30px;
	display:block;
	float:left;
	color: #fff;
	text-align: center;
	text-decoration: none;
	text-shadow: 1px 1px 0px #222;
	text-transform:uppercase;
}
nav li a {
	border-right: 1px solid #555;
}
nav li:last-child a {
	border-right: 0;
}
nav a:hover, nav a:active {
	background-color: #888;
}
nav a#pull {
	display: none;
}
/* Per schermi inferiori a 600px */
@media screen and (max-width: 600px) {
  	nav ul {
  		width: 100%;
  	}
  	nav li {
  		width: 50%;
  		float: left;
  		position: relative;
  	}
  	nav li a {
		text-align: center;
		border-bottom: 1px solid #576979;
		border-right: 1px solid #576979;
	}
  	nav a {
	  	text-align: left;
	  	width: 100%;
	  	text-indent: 25px;
  	}
}
/* Per schermi inferiori a 480px */
@media only screen and (max-width : 480px) {
	nav {
		border-bottom: 0;
	}
	nav ul {
		display: none;
		height: auto;
	}
	nav a#pull {
		display: block;
		background-color: #283744;
		width: 100%;
		position: relative;
	}
	nav a#pull:after {
		content:"";
		width: 30px;
		height: 30px;
		display: inline-block;
		position: absolute;
		right: 15px;
		top: 10px;
	}
}
/* Per schermi inferiori a 320px */
@media only screen and (max-width : 320px) {
	nav li {
		display: block;
		float: none;
		width: 100%;
	}
	nav li a {
		border-bottom: 1px solid #576979;
	}
}

Come possiamo vedere, tramite il CSS non facciamo altro che andare a realizzare un normale menù a tendina con le voci di menù centrate in mezzo alla pagina (grazie all’uso della proprietà inline-block). Se restringiamo la finestra vediamo che raggiunti i 600px le voci si dispongono su colonne da 2 elementi larghi il 50% (per farlo mantenendo i padding in pixel e senza spaccare il layout ricordarsi di usare box-sizing:border-box). Quando invece si arriva a 480px il menù viene nascosto via CSS e mostrato il pulsante “Menù” (id=pull), il quale aziona  al click l’apertura:

jQuery: mostrare e nascondere il menù

$(function() {
	var pull = $('#pull');
	menu = $('nav ul');
	menuHeight = menu.height();
	$(pull).on('click', function(e) {
		e.preventDefault();
		menu.slideToggle();
	});
});

In questo modo deleghiamo a jQuery solo l’azione di mostrare/nascondere il menù, evitando il problema dell’intercettazione del cambio di URL che si ha con la tendina. Una soluzione tutto sommato semplice ma efficace.

NB: Nella demo troverete un mini-fix in js che serve a non far scomparire il menù se lo si apre e chiude e si riallarga lo schermo.

Demo menù responsive