L'effetto parallax è senz'altro, da diversi mesi, uno dei trend più diffusi nel web design. Sul web lo si può vedere declinato nei modi più svariati, dalle realizzazioni più semplici e minimalistiche alle sperimentazioni più ardite e complesse. In questo articolo lo applicheremo al design di una pagina singola suddivisa in sezioni, caratterizzata dalla presenza di grandi foto a tutto schermo alternate a pannelli testuali informativi.
In uno scenario d'uso reale è una soluzione che si presta per tipologie di siti ben precise: portfolio oppure pagine illustrative di un particolare prodotto o servizio. L'ispirazione, tra le tante proposte rintracciabili sul web, viene dalla home page della popolare applicazione musicale Spotify.
Iniziamo subito, proponendo sin da ora il link alla versione finale della nostra demo.
La struttura della pagina: il markup HTML
Questo tipo di pagine presenta una struttura molto semplice.
Di norma si ritrova in alto una testata con un menu di navigazione le cui voci puntano alle sezioni in cui è suddiviso il documento; questo header è di solito fisso, consentendo all'utente di avere sempre a portata di click un modo per muoversi all'interno della pagina. Ecco come abbiamo definito la testata nel nostro esempio:
<header class="menu">
<div class="container">
<nav>
<ul class="navigation">
<li><a href="#slide1">Pannello 1</a></li>
<li><a href="#slide2">Pannello 2</a></li>
<li><a href="#slide3">Pannello 3</a></li>
<li><a href="#slide4">Pannello 4</a></li>
<li><a href="#slide5">Pannello 4</a></li>
<li><a href="#slide6">Pannello 4</a></li>
</ul>
</nav>
</div>
</header>
Dopo l'header ritroviamo una serie di sezioni o pannelli. Si alternano pannelli con grandi foto usate come sfondo e pannelli che nel nostro caso contengono solo testo ma che potrebbero naturalmente ospitare qualsiasi tipo di contenuto.
Nella demo le sezioni sono definite con una serie di elementi section
che costituiscono l'ossatura fondamentale della pagina:
<section class="slide" id="slide1">
[...]
</section>
<section class="slide" id="slide2">
[...]
</section>
<section class="slide" id="slide3">
[...]
</section>
<section class="slide" id="slide4">
[...]
</section>
<section class="slide" id="slide5">
[...]
</section>
<section class="slide" id="slide6">
[...]
</section>
Ogni sezione è identificata con un id
univoco e una classe slide
che ci servirà per impostarne le caratteristiche visuali nel CSS.
Nella demo, per gestire il layout all'interno delle sezioni, sono stati usati la griglia e il markup di Bootstrap 3, ma va bene qualunque soluzione, per l'effetto che vogliamo ottenere è importante solo la struttura delle sezioni così come è stata tracciata qui sopra.
Applichiamo gli stili alle sezioni
Negli esempi allegati all'articolo gli stili specifici delle varie demo sono contenuti nel foglio stile.css
, mentre griglia.css
contiene qualche regola di reset e le impostazioni per la griglia di Bootstrap. Vediamo subito come approcciare la configurazione del layout.
Per prima cosa, prevedendo di avere la sezione iniziale che si presenta come un pannello con una foto a tutto schermo, impostiamo per gli elementi html
e body
un'altezza pari al 100%:
html,
body
{
height: 100%;
}
Per quanto riguarda l'header, basterà dichiarare un posizionamento fisso e uno z-index elevato per porlo sempre in primo piano anche quando si scorrono le sezioni sottostanti:
.menu
{
position: fixed;
top: 0px;
width: 100%;
height: 60px;
background-color: rgba(0,0,0,1.0);
z-index: 100;
}
Passiamo alle sezioni. Come si ricorderà, a tutti gli elementi section
è stata assegnata una classe slide
. Nel CSS useremo questo selettore per riunire in una sola regola gli stili comuni a tutti pannelli. Eccoli:
.slide
{
width: 100%;
position: relative;
padding: 150px 0;
text-align: center;
}
Le regole cruciali, quelle necessarie per la realizzazione del risultato finale, sono le prime due: la larghezza di tutte le section
deve essere del 100%, il posizionamento relativo. Il padding sul lato inferiore e superiore, così come la centratura del testo sono invece facoltativi e modificabili a piacere. Nei nostri esempi abbiamo usato questo padding tanto consistente in alto e in basso (150px) per dare spazio in altezza alle sezioni a prescindere dal contenuto che ospitano. L'alternativa, come vedremo, è di agire sulla proprietà height
.
A questo punto non rimane che lavorare sulle singole sezioni. Quelle con il contenuto testuale sono la 2, la 4 e la 6. Le abbiamo unificate in un unico selettore, visto che nell'esempio hanno caratteristiche visuali identiche:
#slide2,
#slide4,
#slide6
{
background-color:#ffffff;
box-shadow: 0 18px 14px -14px rgba(0,0,0,0.6), 0 -18px 14px -14px rgba(0,0,0,0.6);
z-index: 10;
}
Cosa c'è da osservare? A parte il colore di sfondo, si noti che è stata aggiunta un'ombreggiatura sul lato inferiore e su quello superiore, un effetto puramente decorativo che può naturalmente essere eliminato (o personalizzato). Se si usa la box shadow in questo modo, però, bisognerà pure assegnare uno z-index che sia superiore a quello delle altre sezioni ma inferiore a quello dell'header in modo tale che scorrendo la pagina le sezioni 'passino sotto' alla testata.
E veniamo alle sezioni con lo sfondo fotografico. Qui si tratterà di lavorare essenzialmente sulle proprietà relative al background.
La prima sezione si differenzia dalla terza e dalla quinta solo perché per essa impostiamo un'altezza del 100% per ottenere un effetto tutto schermo. Ecco gli stili:
#slide1
{
height: 100%;
background-image:url('../images/1.jpg');
background-color:#fff;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
}
#slide3
{
background-image:url('../images/2.jpg');
background-color:#fff;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
}
#slide5
{
background-image:url('../images/3.jpg');
background-color:#fff;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
}
Posto che bisognerà scegliere immagini di una certa ampiezza (le nostre sono 1600x800px), lo sfondo non dovrà essere ripetuto (no-repeat
), avere la proprietà background-size
impostata su cover
e, soprattutto, essere fisso (background-attachment: fixed
): lo sfondo fisso è fondamentale per l'effetto parallax e richiesto dal plugin Javascript che useremo per ricrearlo.
Come si vede, la configurazione di base nel CSS non è complicata. Ecco cosa abbiamo finora ottenuto in questa demo che non presenta l'effetto parallax. Un risultato già comunque interessante.
Aggiungere l'effetto parallax, usiamo Stellar.js
Per ricreare l'effetto parallax bisogna necessariamente ricorrere a una soluzione Javascript. Tra i tanti script e plugin disponibili ci affidiamo a Stellar.js, anche perché, per quelle che sono le nostre necessità rispetto all'effetto finale, richiede una configurazione davvero minimale.
Dopo aver incorporato jQuery, da cui il plugin dipende, richiamiamo il plugin:
<script src="js/jquery.stellar.min.js"></script>
E procediamo alla sua semplice inizializzazione:
<script>
jQuery(document).ready(function ($) {
$(window).stellar();
});
</script>
Basta richiamare il metodo stellar()
usando come riferimento l'elemento che contiene gli oggetti a cui applicare l'effetto parallax. Per intenderci, usando window
presumiamo che l'elemento sia la finestra del browser, ma potremmo anche definire un elemento in questo modo:
<script>
jQuery(document).ready(function ($) {
$('#container').stellar();
});
</script>
Lo script così configurato cerca all'interno del documento tutti gli elementi per i quali si siano impostati degli attributi del tipo data-stellar-ratio
o data-stellar-background-ratio
. Il primo tipo si usa per un effetto parallax applicato agli elementi di qualsiasi tipo presenti nel documento, il secondo per un effetto applicato alle immagini di sfondo. Nelle nostre demo ci troviamo ad agire in questo secondo scenario. Pertanto, andiamo ad aggiungere in corrispondenza delle sezioni con gli sfondi l'attributo data-stellar-background-ratio
:
<section class="slide" id="slide1" data-stellar-background-ratio="0.5">
<section class="slide" id="slide3" data-stellar-background-ratio="0.5">
<section class="slide" id="slide5" data-stellar-background-ratio="0.5">
Il valore assegnato all'attributo imposta il fattore di velocità nello scorrimento dell'elemento rispetto al resto della pagina. Un valore di 1
fa sì che l'elemento (o lo sfondo) scorra alla velocità naturale; scendendo sotto 1
si rallenta la velocità relativa; salendo sopra 1
si aumenta. Nel nostro caso si è optato per il valore 0.5
.
Ecco cosa abbiamo ottenuto. Basta fare il confronto con la demo senza parallax per apprezzare le differenze nella resa visuale.
Stellar.js ha chiaramente molte altre opzioni di configurazione, ma se si tratta di applicare il parallax sulle immagini di sfondo i settaggi che abbiamo usato sono più che sufficienti.
Nella seconda parte dell'articolo vedremo come effettuare i ritocchi finali e come lavorare su mobile.
Ritocchi finali
La costruzione della nostra pagina singola con effetto parallax può essere arricchita con almeno un'altra opzione. Agiremo sul menu di navigazione per marcare la sezione attiva man mano che si scorre la pagina e per far sì che il passaggio dal menu alla sezione corrispondente avvenga con uno scrolling morbido.
Anche in questo caso abbiamo a disposizione una miriade di soluzioni. Chi vorrà potrà fare tutto da sé, oppure affidarsi a ottimi plugin per jQuery come Waypoint.js. Noi abbiamo fatto ricorso al plugin Single Page Nav.
Una volta definito il menu di navigazione con tutte le voci che rimandano alla sezione corrispondente, basterà inizializzare lo script in questo modo:
<script>
$('.navigation').singlePageNav({
updateHash: true
});
</script>
Si richiama il metodo singlePageNav
avendo come riferimento l'elemento che contiene il menu di navigazione (.navigation
. Abbiamo anche aggiunto l'opzione updateHash: true
per far sì che quando ci si sposta in una delle sezioni venga aggiornato l'URL nella barra del browser con l'indicazione del frammento del documento in cui ci si trova.
Dal momento che lo script assegna dinamicamente ai link del menu una classe .current
, necessario creare una regola ad hoc nel nostro CSS per specificare gli stili:
a.current
{
color: red;
}
Agire sull'altezza delle sezioni
Un'altro intervento può essere svolto sulle sezioni con immagini di sfondo. In tutte le demo viste finora esse presentavano del testo, la cui presenza, insieme al padding, defniva l'altezza finale delle sezioni stesse, quindi l'area visibile. Possiamo naturalmente lasciare queste sezioni 'libere' da ulteriori contenuti, ma in questo caso si dovrà agire sull'altezza delle singole sezioni per impostare l'area visibile delle immagini. Ecco la demo corrispondente e gli stili applicati alle sezioni:
#slide1
{
height: 100%;
background-image:url('../images/1.jpg');
background-color:#fff;
background-repeat: no-repeat;
-webkit-background-size: cover;
background-size: cover;
background-attachment: fixed;
}
#slide3
{
background-image:url('../images/2.jpg');
background-color:#fff;
background-repeat: no-repeat;
-webkit-background-size: cover;
background-size: cover;
background-attachment: fixed;
height: 600px;
}
#slide5
{
background-image:url('../images/3.jpg');
background-color:#f68f67;
background-repeat: no-repeat;
-webkit-background-size: cover;
background-size: cover;
background-attachment: fixed;
height: 600px;
}
Funzionamento su dispositivi mobili e touch
Chiudiamo con una nota di compatibilità. Qualunque sia la soluzione adottata per implementare l'effetto parallax, va tenuto presente che questo effetto può porre diversi problemi su dispositivi mobili e/o con interfaccia touch, specie quando è applicato sulle immagini di sfondo. Non è un caso che molti plugin prevedono esplicitamente la disabilitazione dell'effetto su questa classe di device. Stellar.js non prevede questa opzione, anche se l'autore ha fornito chiare istruzioni sui modi per estendere il supporto dello script sul mobile.
Se si volesse disabilitare del tutto il parallax sui dispositivi touch si potrà usare, per esempio, una libreria come Modernizr. Lo abbiamo fatto in una demo specifica che contiene alla fine questa istruzione (è invero una soluzione molto 'rozza' ma basterà per rendere l'idea):
<script type="text/javascript">
jQuery(document).ready(function ($) {
if (Modernizr.touch){
$('#slide1, #slide3, #slide5').css('background-attachment', 'scroll');
$('#slide1, #slide3, #slide5').removeAttr('data-stellar-background-ratio');
} else {
$(window).stellar();
}
});
</script>
Con Modernizr testiamo se ci troviamo su un'interfaccia touch, e nel caso svolgiamo due operazioni: modifichiamo il tipo di posizionamento delle immagini di sfondo da fixed
a scroll
(risolvendo un bug osservabile soprattutto su Safari per iOS) ed eliminiamo gli attributi data-stellar-background-ratio
, facendo sì che lo script non venga applicato. Sulle interfacce non touch, procediamo all'inizializzazione regolare.