No. 94

Dieci anni fa, solo i web designer d'avanguardia usavano i CSS per il layout e lo stile. Il supporto da parte dei browser per i layout creati per mezzo dei CSS era povero e pieno di bachi, quindi, queste persone, se da un lato erano favorevoli all'aderenza agli standard web, dall'altro creavano degli hack che permettessero ai layout in CSS di funzionare i tutti i browser. Un hack che si diffuse largamente fu il browser sniffing: individuare quale browser e quale versione l'utente stesse usando, controllando la proprietà navigator.userAgent in JavaScript. Il browser sniffing permetteva il forking del codice in maniera rapida e semplice, permettendo agli sviluppatori di indirizzare i vari browser con istruzioni differenti.

Al giorno d'oggi, i layout basati sui CSS sono una cosa normale e tutti i browser li supportano in maniera piuttosto solida. Ma adesso abbiamo CSS3 e HTML5 e la situazione si sta ripetendo—diversi browser mostrano diversi livelli di supporto a queste nuove tecnologie. Tuttavia, siamo diventati più brillanti e non usiamo più gli hack CSS né tanto meno l'inattendibile e scadente pratica del browser sniffing. Abbiamo inoltre convinto sempre più clienti che i siti web non devono per forza avere esattamente lo stesso aspetto in ciascun browser. Quindi, come gestiamo questo nuovo ma familiare problema? Semplice: usiamo la feature detection, ossia non chiediamo più al browser “Chi sei?” e da lì in poi facciamo assunzioni inaffidabili, bensì chiediamo al browser: “Puoi fare questa e quest'altra cosa?” E' un modo semplice per testare le capacità del browser, ma fare tutti questi test manualmente ogni volta diventa noioso. Per risolvere questo problema (e altri ancora), potete usare Modernizr.

Modernizr: la libreria di feature-detection per HTML5 e CSS3

Modernizr è una libreria open source di Javascript che facilita ai web designer il supporto per i diversi livelli di esperienze, basandosi sulle capacità del browser del visitatore del sito. Ciò permette ai designer di approfittare di tutto quello che HTML5 e CSS3 offrono e che è già implementato in alcuni browser, senza sacrificare il controllo sull'esperienza d'uso in altri browser.

Quando inserite lo script Modernizr nella vostra pagina, questo individua se il browser corrente supporta le feature di CSS3 come @font-face, border-radius, border-image, box-shadow, rgba() e così via, così come le feature di HTML5 come audio, video, localStorage ed i nuovi tipi e attributi dell'elemento <input>. Sapendo ciò, potrete approfittare di queste implementazioni native nei browser che supportano queste feature e decidere se volete creare un fallback basato su JavaScript o semplicemente lasciar degradare gradualmente la pagina nei browser che non le supportano. Inoltre, Modernizr rende disponibili per la progettazione in Internet Explorer i nuovi elementi di HTML5, così che potete usare da subito la loro semantica migliorata.

Modernizr è stato creato basandosi sul principio del "Progressive Enhancement" [miglioramento progressivo, ndr], così da supportare—e perfino incoraggiare— la costruzione di siti layer per layer, partendo da una base senza JavaScript e aggiungendo uno alla volta i livelli di miglioramento. Questa cosa è semplice con Modernizr, dal momento che saprete di cosa è capace il browser. Vediamo un esempio pratico di come usare Modernizr per costruire siti web all'avanguardia.

Primi passi con Modernizr

Per prima cosa, scaricate l'ultima release stabile all'indirizzo www.modernizr.com, dove potete anche trovare la lista completa delle feature che è in grado di rilevare. Una volta che avete l'ultima versione, la 1.5 nel momento in cui sto scrivendo questo articolo, inseritela nella sezione <head> della vostra pagina:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Beautiful Sample Page</title>
<script src="/modernizr-1.5.min.js"></script>

</head>

Dopodiché, aggiungete la classe “no-js” all'elemento <html>:

<html class="no-js">

Quando Modernizr va in esecuzione, rimpiazzerà quella classe con la classe“js” che vi permette di sapere, nel vostro CSS, se JavaScript è attivato oppure no. Ma Modernizr non si ferma qui: aggiungerà le classi per ciascuna feature che individua, usando come prefisso a queste “no-” se il browser non le supporta. Quindi, il vostro elemento <html> sarà siile a questo dopo il pageload (sempre che JavaScript sia attivato):

<html class="js canvas canvastext no-geolocation rgba hsla multiplebgs borderimage borderradius boxshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions video audio localstorage sessionstorage webworkers applicationcache fontface">

Modernizr crea anche un oggetto JavaScript, chiamato semplicemente Modernizr, che ha una lista di proprietà che contengono dei valori booleani per ciascuna feature. Modernizr.canvas sarà vero se il browser supporta il nuovo elemento canvas e falso se il browser non lo supporta. L'oggetto JavaScript contiene inoltre informazioni più dettagliate riguardo alcune feature. Ad esempio, Modernizr.video.h264 vi dirà se il browser supporta quel particolare codec. Modernizr.inputtypes.search vi dirà se il nuovo input type search è supportato. E così via.

La nostra semplice pagina di esempio è un po' spoglia, ma è altamente semantica ed accessibile. Diamole un po' di stile di base, un po' di formattazione, colore e layout per renderla più gradevole alla vista. Fin qui, niente di nuovo: aggiungiamo semplicemente delle proprietà CSS ad una pagina HTML strutturata semanticamente ed il risultato—per quanto semplice— è molto chiaro.

Ora, miglioriamo la pagina e rendiamola più interessante. Voglio usare un font carino (e open license) per lo header h1, dividere la lista di feature in due colonne e spostare la sezione riguardante Modernizr, insieme ad una foto, a destra di tutto. Cambierò anche il bordo intorno alla pagina e lo renderò più carino. Ora, CSS è piuttosto fantastico perché potete semplicemente aggiungere nuove proprietà ad una regola e, se il browser non le riconosce (leggi: supporta), semplicemente le ignorerà. Combinate questo alla natura a cascata dei CSS e potrete usare cose come border-radius senza dover fare affidamento a Modernizr. Tuttavia, l'utilizzo di Modernizr effettivamente offre qualcosa che non potete ottenere senza di esso: la possibilità di cambiare le proprietà che il browser supporta, solo a condizione che supporti altre proprietà. Vi mostrerò ciò aggiungendo due nuove regole CSS alla nostra pagina:

.borderradius #content {
border: 1px solid #141414;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
}
.boxshadow #content {
border: none;
-webkit-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
-moz-box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
box-shadow: rgba(0,0,0, .5) 3px 3px 6px;
}

La prima regola aggiunge un angolo arrotondato di 12 pixel al nostro elemento #content. Tuttavia, la regola originale che avevamo per#content specificava un bordo di “2px outset #666”, che era carino quando il box aveva angoli quadrati, ma adesso, con gli angoli arrotondati, non è così bello. Grazie a Modernizr, potete istruire il browser affinché visualizzi solo un bordo solido di un pixel se il browser supporta border-radius.

La seconda regola spinge la cosa un po' oltre, aggiungendo una drop shadow all'elemento #content e rimuovendo tutto il bordo se il browser non supporta la proprietà box-shadow. Perché? Perché la maggior parte dei browser non rende in maniera molto carina la combinazione border-con-border-radius e box-shadow. (Si noti che questa è una mancanza dei browser, ma è qualcosa con cui siamo costretti a convivere per il momento). Preferirei usare la drop shadow attorno al nostro elemento piuttosto che non usare una drop shadow ma solo un bordo. In questo modo, posso avere tutti i vantaggi, o meglio, tutti i vantaggi di CSS: i browser che supportano la proprietà box-shadow ci mostreranno una drop shadow graziosa, i browser che supportano solo border-radius ci mostreranno degli angoli arrotondati con un bordo più sottile e i browser che non supportano nessuna di queste, mostreranno l'originale bordo di due pixel outset.

Nel nostro prossimo esempio aggiungeremo un font speciale per il nostro header. La nostra dichiarazione originale per h1, che non cambieremo ma che evidenzio qui come esempio:

h1 {
color: #e33a89;
font: 27px/27px Baskerville, Palatino, "Palatino Linotype",
"Book Antiqua", Georgia, serif;
margin: 0;
text-shadow: #aaa 5px 5px 5px;
}

Questa dichiarazione andava bene per la nostra pagina base e la dimensione del font a 27 pixel va bene per tutti questi font, ma è troppo piccola per il nostro font custom, chiamato Beautiful. Aggiungiamo le regole CSS che ci permettono di utilizzarlo:

@font-face {
src: url(Beautiful-ES.ttf);
font-family: "Beautiful";
}
.fontface h1 {
font: 42px/50px Beautiful;
text-shadow: none;
}

Innanzitutto, aggiungiamo la dichiarazione @font-face all'interno della quale specifichiamo il path, il filename e il nome della font-family per il nostro font custom. Poi aggiungiamo la scelta del font in una regola CSS per il nostro elemento h1, ma, come si vede, sto usando un font size troppo grande. Questo accade perché il font Beautiful viene visualizzato molto più piccolo di tutti gli altri font che ho specificato per l'elemento h1, e così dobbiamo istruire il browser affinché visualizzi il nostro header ad una dimensione molto più grande, ma solo quando visualizza il nostro font custom.

Inoltre, il nostro bellissimo script per il font ha alcuni problemi con la visualizzazione della text shadow, quindi tolgo l'ombreggiatura quando il browser decide di visualizzare il font custom. Poi dobbiamo anche dividere la lista delle feature. Per fare ciò, voglio usare la fantastica feature "column" di CSS, che permette al browser di separare in maniera intelligente la lista in colonne senza incasinare il suo ordine—e la nostra lista, sebbene non sia visibilmente numerata, è ordinata alfabeticamente. Ovviamente, non tutti i browser supportano già le colonne CSS, così per questi browser useremo solo il float per dividere la lista su due colonne: non sarà più ordinata alfabeticamente (visivamente), ma è meglio che niente:

.csscolumns ol.features {
-moz-column-count: 2;
-webkit-columns: 2;
-o-columns: 2;
columns: 2;
}
.no-csscolumns ol.features {
float: left;
margin: 0 0 20px;
}
.no-csscolumns ol.features li {
float: left;
width: 180px;
}

Ancora una volta, userò Modernizr per applicare proprietà molto comuni solo sotto determinate circostanze—cosa che non avrei potuto fare tramite la property overloading o la cascata. Se il browser supporta le colonne CSS, il nostro lavoro qui è finito: la lista appare bellissima ed è ancora ordinata alfabeticamente. Se il browser non supporta le colonne CSS, come determinato dalla classe “no-csscolumns” aggiunta all'elemento <html> in quello scenario, usiamo il float per spostare gli elementi della lista ed applicare alcuni margini e width per ottenere un risultato simile. Non è così bello, ma è un miglioramento rispetto ad un'unica lunga lista su una colonna sola.

Come avrete probabilmente notato, sto specificando le mie colonne in maniera differente dalle proprietà border-radius e box-shadow negli esempi precedenti. Questo è dovuto al fatto che, per prima cosa, Opera al momento supporta le colonne CSS solo attraverso il prefisso del produttore, e seconda cosa, Mozilla non riconosce ancora la proprietà abbreviata “columns”: da qui l'uso di -moz-column-count per quel browser.

Con questi ed un paio di altri simili cambiamenti, la nostra nuova pagina appare decisamente migliore.

Concludiamo questo tutorial aggiungendo dell'ulteriore "progressive enhancement" alla nostra pagina. I browser basati su WebKit supportano alcune cose piuttosto carine—CSS transitions, animazioni e trasformazioni tridimensionali— e io voglio mostrarne alcune nel nostro step finale. Ancora una volta, alcune di queste proprietà potrebbero semplicemente essere aggiunte alle nostre regole CSS esistenti ed essere tranquillamente ignorate dai browser che non le supportano, ma altre proprietà interferirebbero con il layout in tutti i browser se le aggiungessi così, perciò userò Modernizr per controllare molto precisamente quando questi miglioramenti vengono applicati e quando no.

Per prima cosa, prepariamo il palcoscenico:

@-webkit-keyframes spin {
0% { -webkit-transform: rotateY(0); }
100% { -webkit-transform: rotateY(360deg); }
}
.csstransforms3d.cssanimations section {
-webkit-perspective: 1000;
}

La regola @keyframes è parte della nuova specifica per le animazioni di CSS, che attualmente è supportata solo da WebKit. Vi permette di dichiarare un path di animazione completo, con qualunque proprietà vogliate, e lo cambia in qualunque step vogliate. Notate che non specificate una durata in questa dichiarazione, solo i key frames stessi—specificate cose come la durata, il loop count e le easing curves quando applicate l'animazione in una regola CSS. Questo vi permette il riutilizzo di una particolare animazione a diverse velocità su elementi diversi, dandovi così la più grande flessibilità. Per maggiori informazioni sull'uso delle animazioni, leggete la specifica W3C Working Draft.

Quindi, applichiamo la nostra animazione—che fa ruotare un elemento in uno spazio 3D— al nostro header secondario:

.csstransforms3d.cssanimations section h2 {
background-image: url(modernizr-logo.png);
overflow: hidden;
-webkit-animation: spin 2s linear infinite;
}

Dal momento che stiamo ruotando in uno spazio 3D, vorrei che l'immagine di sfondo del logo Modernizr appaia carina e anti-aliased, così la sostituisco con una versione PNG. Aggiungo inoltre una proprietà overflow:hidden per nascondere il testo originale nello header, a cui avevamo assegnato un offset di -9999px. Ruotare l'elemento in 3D fa in modo che venga visualizzato durante la rotazione, che era divertente ma non era molto bello da vedersi. Infine, aggiungiamo la regola di animazione, la impostiamo in modo che dure due secondi, lo faccia ruotare in maniera lineare e lo faccia durare all'infinito.

La nostra pagina finale ha un bell'aspetto e ha anche alcune animazioni divertenti visibili nei browser WebKit. Spero che abbiate compreso quanto più controllo potete ottenere sui vostri siti web con Modernizr e quanto è più semplice fare dell'autentico "progressive enhancement". Tuttavia, questo non è tutto ciò che Modernizr può fare in maniera eccellente: è anche prezioso per creare dei fallback JavaScript-driven e per usare nuove feature ganze di HTML5—ma questo è un argomento di cui dovremo parlare un'altra volta.

Illustrazioni: Carlo Brigatti

Share/Save/Bookmark
 

Discutiamone

Ti sembra interessante? Ci sono già 1 commenti, unisciti alla discussione


Cenni sull'autore

Faruk Ateş

Tra il web design e lo sviluppo web, l'attività di freelancer nel campo dell'UX, la fotografia, la scrittura e la programmazione per l'iPad, Faruk Ateş trova sempre più difficile decidere cosa dire nelle short bio.