Come realizzare una navigazione Off-Canvas con CSS Grid
() translation by (you can also view the original English article)
Il pattern off-canvas è un approccio classico della navigazione responsive. Quando il viewport è abbastanza piccolo da giustificarlo, la navigazione di troppo è nascosta "off-canvas" e portata in vista solamente quando si attiva.
Oggi realizzeremo una navigazione off-canvas usando CSS per farla attivare (non è richiesto Javascript) e il nostro buon amico Grid per creare la struttura della pagina. Ecco l'intera pagina demo di quello su cui lavoreremo.
Struttura della pagina di base
Iniziamo costruendo una pagina di base; puntiamo a qualcosa del genere:
Questa è una struttura abbastanza tipica di una pagina semantica; vedrete che tutto rimane in una singola colonna nei viewport piccoli, poi l'aside si sposta sugli schermi più grandi. L'elemento <nav>
è evidenziato in blue per chiarezza.
Ecco il nostro codice:
1 |
<header role="banner"> |
2 |
<h1>Header</h1> |
3 |
</header>
|
4 |
|
5 |
<nav id="nav" role="navigation"> |
6 |
<ul>
|
7 |
<li>
|
8 |
<a href="#">Item 1</a> |
9 |
</li>
|
10 |
<li>
|
11 |
<a href="#">Item 2</a> |
12 |
</li>
|
13 |
<li>
|
14 |
<a href="#">Item 3</a> |
15 |
</li>
|
16 |
</ul>
|
17 |
</nav>
|
18 |
|
19 |
<section role="main"> |
20 |
<article>
|
21 |
<h2>Article</h2> |
22 |
<p>Curabitur orci lacus, auctor ut facilisis nec, ultricies quis nibh. Phasellus id diam sollicitudin, malesuada turpis id, gravida erat. Maecenas placerat elit vel hendrerit convallis. Sed in mauris ut justo vulputate viverra feugiat ac dui. Fusce feugiat arcu in vehicula vehicula. Donec varius justo at nulla aliquet volutpat.</p> |
23 |
<p>Ut id rutrum eros. Nulla tristique, magna et mattis vulputate, mi eros suscipit turpis, nec bibendum turpis nunc feugiat sapien. Nunc arcu est, lacinia id diam quis, sagittis euismod neque. Nullam fringilla velit sed porta gravida. Proin eu vulputate libero. Ut a lacinia enim. Etiam venenatis mauris et orci tempor congue. Sed tempor eros et ultricies congue. Aenean sed efficitur orci. Nulla vel tempus mi.</p> |
24 |
<p>Ut cursus suscipit augue, id sagittis nibh faucibus eget. Etiam suscipit ipsum eu augue ultricies, at rhoncus mi faucibus. In et tellus vitae leo scelerisque fringilla nec at nunc.</p> |
25 |
</article>
|
26 |
</section>
|
27 |
|
28 |
<aside>
|
29 |
<h3>Aside</h3> |
30 |
</aside>
|
31 |
|
32 |
<footer>
|
33 |
<h3>Footer</h3> |
34 |
</footer>
|
Ora aggiungiamo qualche stile visivo e alcune regole Grid.
Spassiamocela con Grid
Iniziamo avvolgendo tutti i nostri elementi strutturali in un elemento contenitore di qualche tipo - questo sarà il nostro contenitore Grid. Sto utilizzando <div class="container"></div>
.
Adesso aggiungiamo qualche stile di base per grid.
1 |
.container { |
2 |
display: grid; |
3 |
grid-template-columns: 1fr; |
4 |
grid-gap: 10px; |
5 |
}
|
Qui dichiariamo che il contenitore dovrà essere display:grid;
, che dovrà avere una singola colonna di una frazione di unità (non strettamente necessaria a questo punto, ma l'abbiamo aggiunta per essere precisi), e che lo spazio tra tutti gli elementi di grid dovrà essere di 10px.
Poi aggiungiamo degli stili visivi per rendere le cose un po' più chiare:
1 |
.container > * { |
2 |
color: #353535; |
3 |
font-size: 1.2em; |
4 |
line-height: 1.5; |
5 |
padding: 20px; |
6 |
background: #d0cfc5; |
7 |
}
|
8 |
|
9 |
.container nav { |
10 |
background: #136fd2; |
11 |
}
|
12 |
|
13 |
nav ul { |
14 |
list-style: none; |
15 |
margin: 0; |
16 |
padding: 0; |
17 |
}
|
18 |
|
19 |
nav a { |
20 |
color: #d0cfc5 |
21 |
}
|
22 |
|
23 |
nav a:hover { |
24 |
text-decoration: none; |
25 |
}
|
Rendiamolo responsive
Aggiungiamo una media query, cosicché quando il viewport raggiunge una certa misura (diciamo 600px) il layout cambia.
1 |
@media only screen and (min-width: 600px) { |
2 |
|
3 |
/* grid */
|
4 |
.container { |
5 |
grid-template-columns: repeat(4, 1fr); |
6 |
}
|
7 |
|
8 |
/* specific item styles */
|
9 |
|
10 |
.container header, |
11 |
.container nav, |
12 |
.container footer { |
13 |
grid-column: span 4; |
14 |
}
|
15 |
.container section { |
16 |
grid-column: span 3; |
17 |
}
|
18 |
|
19 |
}
|
Così ora, sugli schermi più grandi, la dichiarazione grid cambia così grid-template-columns: repeat(4, 1fr);
. Questo ci dà quattro colonne di egual larghezza, così dobbiamo poi dichiarare quanto largo vogliamo ognuno dei nostri elementi strutturali. Header
, nav
e footer
si estenderanno di 4 (estenderanno sulle quattro colonne) mentre section
si estenderà solo su tre, lasciando uno spazio di una colonna per aside
che si riempirà automaticamente.
Infine, qualche stile per modificare il modo in cui appare nav:
1 |
/* nav styles */
|
2 |
nav ul li { |
3 |
display: inline-block; |
4 |
padding: 0 20px 0 0; |
5 |
}
|
Ecco ciò che abbiamo finora:
Avventurarsi nell'Off-Canvas
Questo è un esempio perfetto di come il posizionamento di CSS può ancora funzionare sugli elementi strutturali, anche dentro un Grid dichiarato. Prenderemo la nostra nav, la rimuoveremo dal flusso del documento, e la posizioneremo off-canvas. Gli altri elementi di grid si sistemeranno bene.
Iniziamo con un'altra media query. Abbiamo già la nostra query min-width
, ma questa volta vogliamo solo dare uno stile agli elementi con max-width
. Finché il nostro viewport raggiunge i magici 600px vogliamo che nav sia posizionato off-canvas:
1 |
@media only screen and (max-width: 599px) { |
2 |
|
3 |
#nav { |
4 |
position: fixed; /* or choose `absolute` depending on desired behavior*/ |
5 |
top: 0; |
6 |
bottom: 0; |
7 |
width: 300px; |
8 |
left: -340px; |
9 |
transition: left .3s ease-in-out; |
10 |
}
|
11 |
|
12 |
}
|
Abbiamo dato a nav una larghezza fissa, posizionandolo a sinistra abbastanza da nasconderlo completamente. Abbiamo usato anche position fixed
, benché possiamo anche usare absolute
dipende se vogliamo che nav scrolli con la finestra o meno.
Abbiamo anche notato la regola transition
, che avrà effetto una volta che avremo costruito dei controlli di attivazione.
Attivazione
Avendo fatto sparire il nostro nav, ora abbiamo bisogno di alcuni controlli per riportare indietro ciò che ci serve. Aggiungiamo un link per dare il via ad esso e un link per chiuderlo di nuovo.
Aggiungiamo questo a header:
1 |
<a class="toggle open" href="#nav">open</a> |
e questo a nav:
1 |
<a class="toggle close" href="#">close</a> |
2 |
<!-- you might also want to use a “×” -->
|
Non abbiamo bisogno di aprire il link per essere visibili sugli schermi più grandi, quindi nasconderemo l'elemento .toggle dentro la nostra media query min-width:
1 |
.toggle { |
2 |
display: none; |
3 |
}
|
:target
Quello che è importante nei link sopra è la presenza di un "identificatore di frammento" (nav
nel href). Questi identificatori sono usati dai browser per navigare direttamente verso gli elementi specifici di una pagina. In questo caso, stiamo dirigendo qualunque elemento che combina l'id "nav" e una volta che è stato centrato possiamo dargli lo stile usando la pseudo classe :target
. Non è necessario Javascript!
Aggiungiamo il seguente alla nostra media query con max-width:
1 |
#nav:target { |
2 |
left: 0; |
3 |
}
|
Questo è tutto! Questo è il nostro interruttore.
Ecco cosa abbiamo adesso:
Avrete bisogno di dare un'occhiata all'intera pagina demo per apprezzare pienamente cosa è stato fatto.
Conclusioni
E abbiamo finito! Ho tenuto lo stile al minimo per non essere d'intralcio, ma siate liberi di darvi alla pazza gioia e farlo esattamente come desiderate.
Potreste anche preferire un interruttore Javascript, invece di :target
, nel qual caso abbiate tutti i pezzi a posto per fare anche questo lavoro.
Spero che vi sia piaciuto questo piccolo esercizio con Grid, restate sintonizzati per i prossimi che verranno!
Risorse utili
- Understanding CSS Grid Layout series on Tuts+
- Examining Responsive Navigation: Off Canvas Patterns by Steven Bradley
- Subscribe to csslayout.news