In questo tutorial, creeremo una barra di navigazione che rimarrà con te mentre scorri verso il basso e creeremo anche un espediente nel mix per eliminarlo.
"Tutti amano i nastri" dice Chris Coyier quando parla delle virtù del :prima
e :dopo
pseudo-elementi. Ho visto questi nastri stilizzati a forma di triangolo spuntare su Internet (un esempio di spicco è la pagina Facebook di Introducing Timeline) e, mentre hanno un certo fascino, devo ammettere che l'effetto spaziale che creano non lo fa mi sembra giusto.
Tuttavia, i nastri sono stati apprezzati per una ragione - essi rompono il paradigma di design per lo più piatto a cui siamo tradizionalmente legati, e sono uno dei pochi elementi visivi a farlo in un modo poco appariscente. Ma, come recita l'antico detto, ci dovrebbe essere più di un modo per scuoiare un gatto - quindi, in questo tutorial, proporrò uno stile visivo alternativo per tali elementi, che trovo molto più naturale ed esteticamente piacevole. Spero che vi piaccia e ne faccia buon uso!
In questo tutorial, utilizzeremo uno dei nuovi elementi di HTML5, il nav
tag, come contenitore per un elenco orizzontale di collegamenti. Spiegherò brevemente come renderlo carino usando un po 'di CSS.
Ancora più importante, ti familiarizzerai con le basi del plugin Waypoint di jQuery, che fornirà funzionalità avanzate: mentre l'utente scorre verso il basso, la barra di navigazione resterà nella parte superiore del viewport, oltre a cambiare per indicare la sezione corrente . Come un tocco in più, useremo un altro plugin, ScrollTo, per fornire uno scorrimento fluido e un posizionamento comodo quando l'utente fa clic sui collegamenti di navigazione.
Sono sicuro che hai già familiarità con i vari nuovi elementi introdotti con HTML5. In questo esempio ne faremo uso due: e
. Cominceremo con il seguente:
Una voce abbastanza ampia.
Lorem ipsum ...
Dovremo dare alla nostra barra di navigazione una larghezza esplicita. Rendilo più largo di 28 px rispetto al wrapper e spostalo con un margine sinistro negativo. Diamo anche ai bordi superiori delicatamente arrotondati usando border - * - raggio
, così come alcune imbottiture arbitrarie.
nav position: relativo; larghezza: 928 px; imbottitura: 2em; margin-left: -14px; border-top-left-radius: 14px 7px; border-top-right-radius: 14px 7px;
Successivamente, aggiungeremo una lista non ordinata di collegamenti all'interno della barra di navigazione e ne imposteremo gli elementi display: blocco in linea
per metterli tutti su una sola riga. Non abbiamo bisogno di alcun proiettile, quindi lo faremo anche noi stile elenco: nessuno
nel mix.
nav li display: inline-block; stile elenco: nessuno;
Fino ad ora, dovresti avere qualcosa del genere:
Ora, se solo i CSS ci permettessero di avere più pseudo-elementi (ad es. :: :: dopo dopo
), potremmo facilmente completare i bordi arrotondati della barra di navigazione in modo semanticamente pulito. Ma non possiamo farlo, quindi dovremo aggiungere due non-semantici div
s alla fine del nav
. Dai loro le lezioni nav-sinistra
e nav-destra
(o potresti chiamarli qualcosa di fantasioso, come Castore e Polluce). Sono 14px di larghezza per 14px di altezza e lo sono assoluto
posizionato a 14px dall'estremità inferiore del nav
.
Come visto sopra, il border-radius
la famiglia di proprietà può assumere due valori per ogni angolo. Anche queste possono essere percentuali della larghezza dell'elemento, il che è molto utile: questo approccio consente al raggio del bordo di adattarsi automaticamente alle variazioni delle dimensioni della scatola.
Le piccole "ombre" che completano l'aspetto del nastro della barra di navigazione vengono create utilizzando ::dopo
pseudo-elementi. Anche la loro larghezza e altezza, così come i loro raggi di bordo, sono impostati usando percentuali.
/ * scambia "left" con "right" per gli altri due * / .nav-left position: absolute; a sinistra: 0; fondo: -14px; larghezza: 14px; altezza: 14px; sfondo: # 848a6a; border-bottom-left-radius: 100% 50%; .nav-left :: after content: "; position: absolute; right: 0; width: 66%; height: 66%; background: # 000; border-top-left-radius: 100% 50%; border -bottom-left-radius: 100% 50%;
E abbiamo finito qui!
Dopo essersi sbarazzati della maggior parte della geometria impossibile di nastri a bordi rettilinei, andiamo avanti.
Per ottenere l'effetto di intestazione mobile, utilizzeremo un plugin jQuery chiamato Waypoints, di Caleb Troughton. Il suo unico scopo è attivare eventi quando l'utente scorre verso un determinato elemento. Come vedrai, è estremamente semplice, ma offre molta flessibilità: puoi dare un'occhiata a diversi esempi sulla sua homepage.
Includere jQuery e Waypoint nella tua pagina e iniziamo!
La prima cosa che devi fare è registrare un waypoint chiamando il .waypoint ()
metodo su un elemento. Ovviamente, questo non fa nulla da solo: dovrai definire una funzione di handler per l'evento. Il modo più semplice per farlo è passando a quella funzione come parametro per .waypoint ()
.
Provalo subito: aggiungi il seguente al tuo script e vedi un messaggio pop-up mentre scorri la barra di navigazione.
$ (function () // Quando la pagina è stata caricata, $ ('nav'). waypoint (// crea una funzione waypoint () alert ("Waypoint reached.");));
Ora, per ottenere il nostro effetto desiderato, le cose diventeranno necessariamente un po 'più complicate. Innanzitutto, dobbiamo racchiudere la nostra barra di navigazione in un contenitore, che sarà il nostro vero e proprio waypoint e servire da segnaposto conveniente (maggiori informazioni qui sotto).
Nel tuo CSS, crea la seguente regola CSS. (Mentre ci sei, sposta tutti i margini verticali il nav
potrebbe avere al nav-contenitore
)
.appiccicoso posizione: fissa; inizio: 0;
E siamo pronti per la parte buona! Cambia i contenuti del tuo script nel modo seguente:
$ (function () // Effettua le nostre ricerche DOM in anticipo var nav_container = $ (". nav-container"); var nav = $ ("nav"); nav_container.waypoint (handler: function (evento, direzione) nav.toggleClass ('sticky', direction == 'down');););
Ok, da dove diavolo è venuto tutto questo, giustamente lo chiedi. Beh, probabilmente hai capito che stiamo attaccando un waypoint al nav-contenitore
; solo questa volta, lo stiamo facendo in modo diverso. Invece di passare direttamente la funzione di gestore a .waypoint ()
, lo incapsuliamo in un oggetto. Di per sé, questo non fa differenza: entrambi sono modi completamente validi per fare la stessa cosa. L'oggetto che stiamo passando, però, può contenere diversi altri valori di opzione - quindi usarlo ora rende più coerente il codice in seguito.
La funzione di gestione che abbiamo definito riceve due parametri: il primo è il jQuery standard evento
oggetto, che è di scarso interesse qui. Il secondo è specifico per Waypoint: è una stringa il cui valore è entrambi 'giù'
o 'su'
a seconda del modo in cui l'utente stava scorrendo quando hanno raggiunto il waypoint.
Ora, sapere in che direzione sta andando l'utente è un bit di informazione molto importante, semplicemente perché ci consente di eseguire comportamenti diversi in entrambe le direzioni. Nel corpo della funzione del gestore, stiamo usando una variante relativamente poco conosciuta di jQuery .toggleClass ()
metodo, che rende utile una scorciatoia: in questa sintassi, il secondo parametro determina se la classe verrà aggiunta all'elemento di destinazione o rimossa da essa. Quando l'utente scorre verso il basso, l'espressione direzione === 'down'
valuta a vero
, quindi la nostra barra di navigazione riceve il appiccicoso
classe e si attacca alla parte superiore del viewport. Non appena l'utente esegue nuovamente il backup, la classe viene rimossa dalla barra di navigazione, che ritorna alla sua posizione. Provalo ora.
Splendido, no? Tuttavia, se scorri lentamente oltre il waypoint che hai appena creato, probabilmente noterai che mentre lo passi il contenuto "salta" un po 'a causa della barra di navigazione che viene rimossa dal flusso di contenuti. Oltre a sembrare molto sciatto, un tale comportamento può oscurare parte dei tuoi contenuti e compromettere l'usabilità. Per fortuna, basta una semplice correzione: aggiungere il codice seguente alla funzione del gestore fa andare via il salto.
if (direction == 'down') nav_container.css ('height': nav.outerHeight ()); else nav_container.css ('height': 'auto');
Quello che sta succedendo qui è abbastanza ovvio: noi usiamo nav-contenitore
come segnaposto, come menzionato sopra. Quando scorriamo verso il basso, espandiamo la sua altezza e il contenuto sottostante rimane al suo posto. C'è un problema, tuttavia, affinché funzioni così com'è, è necessario applicare a qualsiasi margine verticale che si potrebbe desiderare di avere attorno alla barra di navigazione nav-contenitore
e non al nav
.
Quindi eccolo! Abbiamo una bella barra di navigazione fissa, come già fanno molti altri siti. Lo spettacolo è finito, gente ...
… o è? Bene, c'è ancora un trucco o due che potresti voler vedere, e che potrebbero solo metterti in vantaggio. Se è così, continua a leggere.
Se ci pensi, ci sono molti casi in cui l'attivazione di un evento quando un elemento raggiunge il bordo della finestra del browser non è quello che vuoi fare. Fortunatamente, Waypoint fornisce un'opzione conveniente per questo: compensare
. Ecco come appare:
nav.waypoint (handler: ..., offset: 50)
compensare
consente di creare il waypoint effettivo a una distanza variabile dalla parte superiore dell'elemento. Un valore positivo attiva il waypoint quando la parte superiore dell'elemento si trova alla distanza specificata sotto la parte superiore della finestra e un valore negativo attiva il waypoint quando l'elemento si trova molto sopra la parte superiore della finestra (ovvero l'utente ha fatto scorrere oltre la parte superiore della finestra ).
Il valore di offset può essere un numero (che rappresenta una quantità fissa di pixel), una stringa contenente una percentuale (interpretata come percentuale dell'altezza del viewport) o una funzione che restituisce un numero di pixel. L'ultimo può fornire una certa flessibilità, e ne faremo un uso in seguito. Per ora, restiamo fedeli ai valori fissi e vediamo a cosa servono.
La prima cosa che viene in mente è aggiungere dello spazio sopra l'elemento appiccicoso. Usando il compensare
variabile, questo è facile: per un offset di 15 pixel dall'alto, aggiungi offset: 15px
a .waypoint ()
le opzioni e cambia top: 0px
a top: 15px
nel .appiccicoso
Regola CSS.
Se il tuo design lo richiede, un piccolo gradiente sopra la barra di navigazione potrebbe anche essere un bel tocco. Questo si ottiene facilmente aggiungendo un altro div
dentro il nav
, e scrivere un po 'di CSS:
.appiccicoso .nav-above position: absolute; top: -15px; a sinistra: 1em; destra: 1em; altezza: 15px; sfondo: gradiente lineare (superiore, rgba (255,255,255,1) 0%, rgba (255,255,255,0) 100%); / * aggiungi il codice gradiente per il cross-browser secondo necessità * /
Questo bel po 'di eye candy funzionerebbe bene in design minimalisti.
Una cosa che Caleb ha attentamente incluso in Waypoint è la possibilità di generare un offset del waypoint in modo dinamico, in questo modo:
nav.waypoint (handler: ..., offset: function () return - (nav.outerHeight () + 50);)
Questo ci permette di avere un gestore che si innesca quando l'utente ha già fatto scorrere 50px oltre il fondo dell'elemento, senza dover conoscere la sua altezza in anticipo.
Nota: Tali offset generati proceduralmente (come quelli dati come percentuali), vengono ricalcolati ogni volta che la finestra viene ridimensionata, vengono aggiunti nuovi waypoint o vengono modificate le opzioni di un waypoint. Se stai facendo qualcos'altro che potrebbe influenzare le posizioni dei waypoint (come cambiare il DOM o il layout di pagina), assicurati di chiamare $ .waypoints ( 'Aggiorna')
in seguito per le posizioni da ricalcolare.
Nel contesto del nostro tutorial, un utilizzo per questa funzionalità scorre agevolmente la barra di navigazione dall'alto. Preparati: il seguente è il più grande pezzo di codice finora. Non dovrebbe esserci nulla in esso che non abbiate già familiarità con, quindi, ecco qui:
var top_spacing = 15; var waypoint_offset = 50; nav_container.waypoint (handler: function (event, direction) if (direction == 'down') nav_container.css ('height': nav.outerHeight ()); nav.addClass ("sticky"). stop () .css ("top", -nav.outerHeight ()) .animate ("top": top_spacing); else nav_container.css ('height': 'auto'); nav.removeClass ("sticky") .stop () .css ("top", nav.outerHeight () + waypoint_offset) .animate ("top": "");, offset: function () return - (nav .outerHeight () + waypoint_offset););
Non troppo malandato! È una tariffa jQuery piuttosto standard: non appena aggiungiamo o rimuoviamo il appiccicoso
classe al nav
, sovrascriviamo la posizione verticale dell'elemento usando .css ()
, e poi .animare()
a ciò che dovrebbe essere. Il .Stop()
serve per prevenire possibili bug eliminando la coda degli eventi di jQuery.
C'è un piccolo effetto collaterale su questo, anche se - dato che il codice assume effettivamente la posizione verticale dell'elemento di navigazione quando è fisso, si potrebbe anche top: 15px
dichiarazione dal tuo CSS. Se fai parte di un grande progetto, con persone separate che lavorano su design e scripting front-end, questo potrebbe costituire un problema poiché è facile perdere traccia di tali hack. Solo per farti sapere, esistono plug-in, come l'eccellente jQuery.Rule di Ariel Flesler che può essere utilizzato per colmare il divario tra script e fogli di stile. Dovrai decidere da solo se hai bisogno di qualcosa del genere.
Potresti sicuramente ottenere un effetto simile con i CSS @keyframes
invece, ma c'è molto meno supporto per loro (e molti prefissi dei venditori), sono meno flessibili, e l'animazione "su" sarebbe un grande no-no. Dal momento che non stiamo lasciando la traccia del miglioramento progressivo, non c'è ragione di non restare fedeli alle solide funzionalità di jQuery.
Potresti trovarti a dover cambiare l'elemento evidenziato mentre il lettore avanza oltre le diverse sezioni della pagina. Con Waypoint, questo è abbastanza facile da raggiungere. Dovrai aggiungere quanto segue al tuo script:
$ (function () ... // copia da qui ... var sections = $ ('section'); var navigation_links = $ ('nav a'); section.waypoint (handler: function (evento, direzione) // codice gestore, offset: '35% '); // ... a qui);
Questa volta stiamo usando un offset espresso come percentuale dell'altezza della finestra. In pratica, ciò significa che la linea immaginaria che indica al nostro script quale sezione è attualmente visualizzata è posizionata a circa un terzo dalla parte superiore del viewport - proprio dove l'osservatore guarderebbe durante la lettura di un lungo testo. Una soluzione più robusta potrebbe utilizzare una funzione per adattarsi ai cambiamenti nell'altezza della barra di navigazione.
Il codice che useremo nella nostra funzione di gestore è un po 'meno auto-esplicativo, però. Ecco qui:
var active_section; active_section = $ (this); if (direction === "up") active_section = active_section.prev (); var active_link = $ ('nav a [href = "#' + active_section.attr (" id ") + '"]'); navigation_links.removeClass ( "selezionato"); active_link.addClass ( "selezionato");
Per prima cosa, dobbiamo sapere quale sezione è attualmente visualizzata. Se stiamo scorrendo verso il basso, la sezione a cui appartiene il waypoint è la stessa che diventa attiva. Scorrendo oltre un waypoint, tuttavia, significa che è la sezione precedente che viene visualizzata, quindi usiamo .prev ()
per selezionarlo. Quindi, rimuoviamo il selezionato
classe da tutti i link nella barra di navigazione, prima di applicarla nuovamente a chi di cui href
l'attributo corrisponde al id
della sezione attualmente attiva.
Funziona molto bene; se si desidera andare oltre l'aggiunta e la rimozione di classi, si potrebbe voler esaminare un plugin come LavaLamp.
Ad un certo punto, potresti aver notato che cliccando sui collegamenti nella barra di navigazione posiziona la parte superiore della sezione nella parte superiore della finestra del browser. Questo è abbastanza intuitivo quando non c'è nulla che oscuri quella parte dello schermo; ora che abbiamo una barra di navigazione lì, diventa un enorme fastidio. È qui che ScrollTo di Ariel Flesler viene in soccorso. Inseriscilo nella tua pagina, quindi aggiungi il seguente codice:
navigation_links.click (function (event) $ .scrollTo ($ (this) .attr ("href"), duration: 200, offset: 'left': 0, 'top': - 0.15 * $ (finestra) .altezza() ); );
(naturalmente, quel codice supera l'ultima parentesi graffa!)
Sebbene ci siano modi migliori per associare una funzione agli eventi di click, ci atteniamo a quella più semplice: .clic()
. Il .scrollTo ()
il metodo è chiamato in un modo molto simile a .waypoint ()
. Richiede due parametri: un oggetto di scorrimento e un oggetto contenente diverse opzioni, che, in questo caso, sono piuttosto auto-esplicative. Il link cliccato href
l'attributo funziona bene come un oggetto di scorrimento e l'espressione usata come offset superiore posiziona il target al 15% dell'altezza del viewport.
E sembra che abbiamo finito. Ti ho presentato il pratico plugin che è Waypoints e abbiamo esaminato alcuni casi di utilizzo che dovrebbero darti un'idea delle varie cose che potresti ottenere con esso. Abbiamo anche implementato un comportamento di scorrimento molto più intuitivo per andare con la nostra navigazione. Getta un po 'di Ajax nel mix e sei sulla buona strada per costruire quel tipo di esperienza Web coinvolgente e senza interruzioni che sarà il futuro del Web ... beh, più probabilmente sarà alla moda per un po' e poi diventerà luogo comune, rendendo i veterani del Web nostalgici sul modo in cui erano le cose. Ma hey, ecco come vanno le cose.
Per quanto riguarda i nastri, il loro più grande inconveniente è questo: sono solo un'illusione. I lati del nastro non si muovono effettivamente attorno ai bordi del contenitore; appaiono solo in questo modo, il che diventa abbastanza ovvio quando il nastro passa sopra un elemento che sporge dal bordo della pagina.
A causa di come funziona z-index, non sembra esserci un modo semplice per risolvere questo conflitto, salvo evitarlo in primo luogo. Tuttavia, con un po 'di immaginazione, oltre a una conoscenza di base di jQuery, potresti creare un modo per questi elementi uscire dalla barra del nastro mentre si avvicina a loro. Questo però va ben oltre lo scopo di questo tutorial; spero di poterlo mostrare prima o poi sotto forma di un suggerimento rapido, qui o su Nettuts +. Rimanete sintonizzati!