Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Architetture CSS: Ristrutturare i CSS con l'approccio MetaCoax

Buone pratiche per la ristrutturazione dei CSS. Un processo in varie fasi in cui rivedere selettori, dichiarazioni raggruppamenti e condivisioni.
Buone pratiche per la ristrutturazione dei CSS. Un processo in varie fasi in cui rivedere selettori, dichiarazioni raggruppamenti e condivisioni.
Link copiato negli appunti

I principali approcci scalabili e modulari che abbiamo analizzato nell'articolo precedente hanno tutti elementi molto interessanti e che possono aiutarci a modificare il modo in cui pensiamo alla struttura di un foglio di stile. In molte aree si sovrappongono, un fattore che illumina bene quegli aspetti del processo di ottimizzazione dei CSS che sono davvero critici.

Sebbene si possa seguire un singolo approccio nel momento in cui si debba mettere mano alla costruzione di un nuovo sito, ciò che realmente conta è provare a mettere ordine in CSS che altrimenti rischiano di essere del tutto fuori controllo.

Così, sebbene gli approcci presentati siano di per sé ottimi, ciò di cui abbiamo bisogno davvero è un modo per combinare il meglio di ciascuno per combattere il codice confuso e disorganizzato, una sorta di 'grande coalizione' delle migliori tecniche offerte dagli approcci scalabili e modulari.

Inoltre, proprio come Roma non è stata costruita in un solo giorno, è assurdo pensare di provare a correggere in un colpo solo migliaia di righe di codice mal concepito e mal strutturato. Dunque, è una buona idea soffermarsi sul codice in momenti successivi, concentrandosi ogni volta su aspetti diversi nelle varie fasi di questa analisi.

Trovare un buon nome per questa ottimizzazione dei CSS

L'anno scorso, mi è stato affidato da un cliente un lavoro che richiedeva di svolgere un'operazione del genere. Dopo aver studiato DRY CSS, OOCSS, SMACSS e CSSG, ho pensato fosse opportuno distillare questi approcci rispetto a quelle che sono le loro pratiche essenziali. A un certo punto ho realizzato che tutti possono essere riportati, in sintesi, ad un vecchio adagio: "misura due volte, taglia una sola volta". Certo! Tutti questi approcci invitano a definire pattern, a creare stili portabili e moduli riusabili, a non aggiungere selettori di stili superflui e ridondanti.

E allora, ho stilato un piano di attacco per ridurre il numero delle righe di codice. Alla fine ho utilizzato specifiche tecniche da ciascuno dei quattro approcci di cui sopra e ho verificato che l'approccio che avevo adottato era assolutamente efficace nella riduzione delle righe di codice.

Una volta creato il processo, ho cercato di dargli un nome. È venuto fuori MetaCoax. In questo articolo cercherò di spiegare come funziona. Per avere una visione completa potete anche consultare le slide della mia presentazione sull'ottimizzazione dei CSS.

Per prepararvi al meglio a questo processo di ristrutturazione, ecco alcuni suggerimenti preliminari. Prima di tutto, siate consapevoli delle regole relative alla specificità e alla cascata.

Ricordo che selettori e regole troppo specifici limitano la possibilità di poterli riusare convenientemente. Soprattutto quando si usano i selettori discendenti, possiamo facilmente perdere il controllo sulla specificità, e ciò è esattamente quello che stiamo provando ad evitare.

Seconda cosa: ricordate le regole sull'ereditarietà. Certe proprietà sono ereditate dagli elementi figli, dunque il modo in cui queste proprietà subiscono la cascata nel contesto del DOM va sempre tenuto presente.

Il processo MetaCoax

Il processo MetaCoax si articola in quattro fasi. Ciascuna fase si basa su quella precedente. Tutte hanno come obiettivo la riduzione del codice, l'aumento della scalabilità e dalla manutenibilità. Inoltre, sono un buon fondamento per un sito a prova di futuro.

  1. Abbreviare i selettori e usare con accortezza le dichiarazioni
  2. Ristrutturare, aggiustare e modularizzare
  3. Snellire i selettori, raggruppare e separare
  4. Condividere

Nella prima parte ci occuperemo delle fasi 1 e 2, mentre copriremo nella successiva la 3 e la 4.

Fase 2: ristrutturare, aggiustare e modularizzare

Le tecniche che analizzeremo nella fase 2 prevedono una mole di lavoro mediamente elevata per ottimizzare il CSS di un sito. Le modifiche toccano sia il CSS sia il codice HTML. Le modifiche all'HTML prevedono più che altro di rinominare nomi di classe o di assegnarne altri. L'obiettivo è quello di dare struttura e organizzazione al foglio di stile raggruppando gli stili per categorie, rimuovendo parti di HTML obsolete, semplificando i selettori e creando moduli in grado di rendere il codice e la sua manutenibilità più efficiente.

In questa fase, dunque, ridurremo ulteriormente la ridondanza e renderemo il CSS ancora più leggero. È un livello di ottimizzazione che richiede più lavoro rispetto alla fase 1, ma comprende il grosso del lavoro da fare per migliorare decisamente il CSS e tagliare drasticamente il numero di righe di codice.

Ecco cosa faremo:

  • Ristrutturare per ottimizzare
    • Suddividere le regole CSS in categorie
    • Ristrutturare gli stili basati sull'uso di riferimenti ad elementi HTML posti in alto nell'albero DOM
    • Usare nomi di classe come selettori chiave
  • Iniziare a costruire moduli
    • Estendere i sotto-stili di un modulo ricorrendo al trattino doppio (--)
  • Creare stili di ausilio pronti per l'uso
    • Stili di ausilio per il layout
    • Stili di ausilio per la tipografia
  • Correggere l'HTML
    • Eliminare gli stili inline
    • Diminuire l'uso del tag span per migliorare la semantica

Ristrutturare per ottimizzare

Con le pratiche che analizzeremo in questa sezione operiamo un cambiamento importante nel modo stesso in cui concepiamo un foglio di stile. Invece che creare stili basati sui componenti e sulla gerarchia della pagina, dobbiamo imparare a creare stili portabili, modulari e riusabili.

Suddividere le regole CSS in categorie

Un primo passo da compiere consiste nel creare una tavola dei contenuti, una sorta di indice, per trovare più facilmente una certa sezione del foglio di stile. In questa fase di ottimizzazione, si raccomanda di affinare questo processo trasformando le voci dell'indice in sezioni del CSS, sezioni che coincidano con i tipi di stile che descrivono e che seguano le categorie definite nell'approccio SMACSS. Queste categorie sono:

  • Stili di base: sono gli stili di default, di solito per selettori composti di elementi singoli.
  • Layout: suddividono la pagina in sezioni, di solito comprendendo e tenendo insieme diversi moduli.
  • Moduli: parti riusabili, modulari del design (sezioni delle barre laterali, liste di prodotti, etc.).
  • Stato: descrive come un modulo o il layout appaiono in uno stato particolare, anche in differenti visualizzazioni della pagina.
  • Tema: descrive come un modulo o il layout appaiono a livello visuale.

Dunque, l'indice del CSS e la suddivisione in sezioni saranno così definite:

/* Indice/Tavola dei contenuti
- Base
- Layout
- Module
- State
- Theme
*/
...
(Sezioni del CSS con gli stili)
/* =Layout */
...
/* =Module */ (etc.)
...

Questa riorganizzazione del foglio di stile aiuta a gettare le basi per tutte le operazioni che svolgeremo in questa fase 2.

Ristrutturare gli stili in posizioni alte del DOM

Questa indicazione è una delle più importanti di tutto l'articolo: bisogna eliminare completamente gli stili che siano specifici di una pagina. Parliamo di quegli stili che sono basati sull'aggiunta di una classe all'elemento body, un'aggiunta che serve a segnalare una pagina che si differenzia in qualche modo dalle altre del sito. Questi stili costringono il browser a cercare un elemento lungo tutto l'albero DOM fino al tag body. Ecco un esempio nel quale si suppone che nel codice HTML siano state assegnate all'elemento body le classi .donations e .event:

body.donations.events div#footer-columns div#col1 div.staff span.slug {
display: block;
margin: 3px 0 0 0;
}

Questa pratica è alla radice delle tipiche lunghe catene di selettori di cui abbiamo parlato, della specificità troppo elevata di certi selettori e della necessità di ricorrere alla parola chiave !important per sovrascrivere stili, come nell'esempio che segue:

body.video div#lowercontent div.children.videoitem.hover a.title { background: #bc5b29;
color: #fff !important;
text-decoration: none;
}

In altre parole, è una cattiva pratica.

Per correggerla, basterà seguire tutti i suggerimenti visti in precedenza. IL primo snippet di codice potrebbe risultare in qualcosa del genere dopo gli interventi:

.donations-slug {
display: block;
margin: 3px 0 0 0;
}

Usare nomi di classe come selettori chiave

Dal momento che gli id hanno una specificità molto alta, dovrebbero essere evitati il più possibile. Infatti, non possono essere riusati come le classi.

Nella creazione delle classi, poi, si dovrebbero scegliere i nomi in modo che siano al tempo stesso portabili e semantici. L'obiettivo è di rendere un selettore il più diretto possibile per evitare problemi di specificità.

Seguendo le indicazioni dell'approccio SMACSS, è opportuno ricorrere alla pratica di usare come selettore chiave una classe invece che un nome di tag o un id. Tenete sempre in mente che il selettore posto all'estrema destra è quello chiave, il più importante. Bisogna fare in modo che tale selettore chiave sia quanto più specifico possibile rispetto all'elemento cui si riferisce. In questo modo, gli stili sono indirizzati più direttamente perché il browser trova subito la corrispondenza con l'elemento.

Dunque, rivedete tutti i punti del CSS in cui sono usati selettori di figli (o altri selettori combinatori) e, quando possibile, sostituiteli con classi specifiche. Per esempio, invece di fare così

#toc > li > a

è meglio creare una classe e aggiungerla agli elementi appropriati:

.toc-anchor

Iniziare a costruire moduli

Negli approcci scalabili ai CSS, nulla sintetizza meglio il vecchio adagio "misura due volte, taglia una volta sola" come i moduli, che di tali approccio sono l'anima e il cuore.

I moduli sono componenti di codice che possono essere astratti dai pattern di design. Un esempio: liste di item con immagini che possono essere floattate a destra o sinistra, oppure collocate in basso (si pensi alla successione di commenti in calce a un post di Facebook, N.d.T). Questo scenario di design può essere astratto in un modulo con un set di stili di base che può essere condiviso con tutti i moduli. Il modulo può essere poi esteso con modifiche al testo, allo sfondo, al colore dei font, ai bordi, ai float e così via. Quella che rimane invariata è la struttura.

Il più grande vantaggio dei moduli è che sono portabili, ovvero non dipendono dalla posizione. Astrarre un pattern di design in un modulo di codice significa che potrete inserirlo dovunque in una pagina e sarà visualizzato allo stesso modo. La modularizzazione dei CSS è uno dei modi migliori per far diminuire in modo drastico la quantità di codice.

L'approccio OOCSS (Object-Oriented CSS) fornisce ottimi spunti rispetto a come strutturare ed estendere un modulo. Anche l'approccio SMACSS offre chiare linee guida su come assegnare nomi ai moduli e su come estenderli.

Estendere i sotto-stili con il trattino doppio (--)

Sebbene SMACSS dia ottimi suggerimenti rispetto all'estensione dei moduli, io preferisco la tecnica prevista nell'approccio CSS for Grownups: estendere i sotto-stili con l'uso del trattino doppio, --. Ciò ha molto senso per quanto mi riguarda, perché il trattino doppio rappresenta un'indicazione visuale che il nuovo stile è basato sul precedente, ma, appunto, lo estende.

Ecco un esempio:

#go, #pmgo{
width: 29px;
height: 29px;
margin: 4px 0 0 4px;
padding: 0;
border: 0;
font-size: 0;
display: block;
line-height: 0;
text-indent: -9999px !important;
background: transparent url("/images/go.jpg") 0 0 no-repeat;
cursor: pointer; /* hand-shaped cursor */
x-cursor: hand; /* for IE 5.x */
}
#pmgo{
margin: 2px 0 0 3px;
background: transparent url("/images/go.jpg") no-repeat center top;
}

Questo codice potrebbe essere modificato così:

.button-search{
width: 29px;
height: 29px;
margin: 4px 0 0 4px;
padding: 0;
border: 0;
font-size: 0;
display: block;
line-height: 0;
text-indent: -9999px !important;
background: transparent url("/images/go.jpg") 0 0 no-repeat;
cursor: pointer; /* hand-shaped cursor */
x-cursor: hand; /* for IE 5.x */
}
.button-search--pm{
margin: 2px 0 0 3px;
background: transparent url("/images/go.jpg") no-repeat center top;
}

Creare stili di ausilio pronti per l'uso

Insieme alla modularizzazione, gli stili portabili sono un altro strumento utile da avere sempre a disposizione. Ecco alcuni esempi suggeriti dall'approccio CSS for Grownups.

Stili di ausilio per il layout

Secondo gli standard fissati in CSS for Grownups, non c'è problema nell'avere qualche ausilio aggiuntivo relativo al layout. Se una buona griglia copre bene la maggior parte delle problematiche, questi stili ausiliari possono servire a correggere dettagli minori in specifiche circostanze (specie nella gestione dello spazio verticale) e a ridurre la quantità di codice. Per esempio, quando e se dovessimo assegnare un margine inferiore o superiore, risulterebbe utile creare due classi ad hoc come queste, riusabili e pronte per l'uso:

.margin-top {margin-top: 5px;}
.margin-bottom {margin-bottom: .5em;}

Sebbene nella maggior parte dei casi facciamo di tutto per creare nomi di classe semantici, in questo scenario nomi descrittivi vanno più che bene.

Stili di ausilio per la tipografia

Gli stili di ausilio per la tipografia sono perfetti se scoprite che la maggior parte del vostro CSS è riservata alla gestione dei font, alla dimensione del testo, all'altezza di riga, etc. Sia OOCSS sia CSS for Grownups suggeriscono l'adozione di stili tipografici ausiliari che non siano legati agli elementi, come questi, che fanno riferimento a diversi stili per i titoli della pagina:

.h-slug {font-size: .8em;}
.h-title {font-size: 1.5em;}
.h-author {font-size: 1em;}

Correggere l'HTML

Se le pratiche delle fasi 1 e 2 finora analizzate possono fare miracoli rispetto alla ripulitura del codice CSS, non possiamo dimenticare il markup della pagina. Come suggerisce Andy Hume, molto probabilmente sarà necessario fare modifiche che vanno oltre la semplice aggiunta di nomi di classe.

Diminuire l'uso del tag span

Avete, nel vostro codice HTML, una gran quantità di elementi span al posto di tag che risulterebbero semanticamente più appropriati? Ricordate, il tag span serve a designare elementi inline, non elementi blocco, come chiarisce bene il W3C. Usare span per titoli o altri elementi blocco è tecnicamente errato.

In questo snippet di codice, per esempio, gli span dovrebbero essere paragrafi o titoli che indichino dove e come il contenuto si colloca nella gerarchia del documento:

<li class="item">
<a href="/learning/hillman" title="">
<img src="/images/brenda-hillman.jpg" alt="Air in the Epic" />
</a>
<span class="slug">Brenda Hillman Essays</span>
<span class="title"><a href="/learning/hillman"
title="Air in the Epic" class="title">Air in the Epic</a></span>
<span class="author">Brenda Hillman</span>
</li>

Questa versione del codice sarebbe un indubbio miglioramento dal punto di vista semantico:

<li class="item">
<a href="/learning/hillman" title="">
<img src="/images/brenda-hillman.jpg" alt="Air in the Epic" />
</a>
<p class="slug">Brenda Hillman Essays </p>
<h3 class="title"><a href="/learning/hillman"
title="Air in the Epic" class="title">Air in the Epic</a></h3>
<p class="author">Brenda Hillman</p>
</li>

Eliminare gli stili in linea

Per concludere, bisogna eliminare del tutto gli stili in linea. Oggi questa tipologia di stili non dovrebbe essere usata. Sono troppo strettamente legati all'HTML e ci riportano ai giorni in cui impazzava l'uso del tag font. Se usate stili in linea per sovrascrivere altri stili a livello di specificità, allora le altre regole suggerite nell'articolo sono un buon punto di partenza per evitare il problema e i conflitti tra stili, rendendo così inutile ricorrere a stili in linea.

Per esempio, questo stile in linea

<span class="text-indent: 1em">Skittles are tasty</span>

potrebbe facilmente essere trasformato in una classe ad hoc che può essere applicata in tutto il documento, così:

.indent {text-indent: 1em:}

Dunque, mettetevi alla ricerca di tutte le ricorrenze di stili in linea nel codice HTML e provate a trasformarli in classi di ausilio portabili.

Fase 1: abbreviare i selettori e usare con accortezza le dichiarazioni

La prima fase richiede un lavoro minimo per migliorare il CSS del sito. Queste modifiche richiedono cambiamenti al CSS ma non al codice HTML. L'obiettivo è di alleggerire il foglio di stile, rendendolo più facile da mantenere, con poco sforzo e con poco tempo. Il metodo richiede l'ottimizzazione dei selettori, riducendo al contempo la ridondanza grazie a un riuso intelligente delle regole e delle dichiarazioni.

Anche se applicherete solo le pratiche di questa fase, otterrete un bel miglioramento nel codice dei vostri CSS. Ecco cosa faremo:

  • Abbreviare le catene di selettori
    • Eliminare i selettori discendenti
    • Eliminare i riferimenti agli elementi HTML
    • Ridurre la catena del selettore a tre o meno elementi
  • Usare con accortezza le dichiarazioni
    • Ottimizzare il meccanismo della cascata sfruttando l'ereditarietà
    • Rivedere e ridurre l'uso della parola chiave !important
    • Non ripetere le regole e le dichiarazioni

Abbreviare le catene di selettori

Per ottimizzare al meglio i selettori, l'obiettivo è di usare catene di selettori corte, accorciando la catena stessa il più possibile. Questa pratica consente di lavorare meglio sul codice perché gli stili diventano più portabili. Un altro vantaggio è che si riduce la possibilità di spezzare il selettore. Inoltre, si evitano possibili conflitti tra gli stili.

Ci sono molti modi per accorciare la catena dei selettori, sono previsti da tutti gli approcci scalabili che abbiamo analizzato nel precedente articolo e tutti questi modi poggiano sull'idea di ridurre, riusare e riciclare. Cominciamo con la prima tecnica.

Eliminare i selettori discendenti

Il selettore discendente (a b) è uno dei meno efficienti da usare per selezionare un elemento. Altri selettori CSS poco efficienti sono il selettore universale (*) e il selettore di figli (a > b). Cosa li rende poco efficienti? Sono molto generici, e dunque costringono il browser a cercare tra più elementi presenti nel documento per trovare la corrispondenza. Più è lunga la catena del selettore, più il browser dovrà cercare e controllare, impiegando un tempo maggiore per rendere a schermo gli stili. Di fronte a un selettore di discendenti, il browser deve trovare ogni ricorrenza di un elemento chiave (quello più a destra) per poi risalire lungo l'albero dei suoi antenati per trovare l'elemento corrispondente.

Se questo potrebbe non essere un problema in un foglio di stile di qualche centinaio di righe, può diventarlo quando la dimensione di un documento si avvicina alla 10000 righe o più. Un fattore ancora più importante è che adottando un approccio mobile-first, lunghe catene di selettori creano una situazione in cui dispositivi meno capaci sono costretti a caricare e processare senza che ve ne sia la necessità documenti CSS di grandi dimensioni.

L'eccessiva dipendenza dal selettore discendente è un'eredità dei giorni in cui si dovevano adattare i CSS a Internet Explorer 6, dal momento che quel browser non supportava gli altri selettori combinatori dei CSS 2.1. Ora che l'utilizzo di Internet Explorer 6 è pressoché nullo negli USA e nel resto del mondo, possiamo usare tranquillamente quei selettori che sono invece pienamente supportati già in IE7 e IE8, facendo a meno di ricorrere pesantemente ai selettori discendenti. La tabella in figura 1 mostra i selettori che possono essere usati su IE7. Le versioni successive di Internet Explorer supportano invece tutti i selettori indicati.

Figura 1 - Supporto dei selettori CSS 2.1 su Internet Explorer 7

screenshot

Per verificare il supporto dei selettori potete anche consultare le tabelle e i grafici disponibili su http://caniuse.com/ e http://www.findmebyip.com/litmus/.

Invece di usare i selettori discendenti, dunque, meglio usare il selettore di figli. Esso seleziona elementi che siano discendenti diretti dell'elemento parente, ovvero suoi figli diretti, di primo livello. La figura mostra il processo di selezione dei due tipi.

Figura 2 - Selettore discendente vs. selettore di figli

screenshot

Sebbene il selettore di figli sia ancora un selettore poco efficiente, è comunque più specifico. Significa che il browser non dovrà cercare a fondo nella catena dell'ereditarietà per trovare una corrispondenza all'elemento chiave. Dunque, il selettore di figli identifica il suo target in modo molto più efficace.

Se proprio dovete usare un selettore di discendente, eliminate tutti gli elementi superflui. Per esempio:

.widget li a

potrebbe diventare

.widget a

Lo stile verrà applicato a prescindere dalla presenza dell'elemento li.

Eliminare i riferimenti agli elementi HTML

Qualificare id e classi con l'indicazione degli elementi HTML corrispondenti fa sì che il browser debba ricercare, senza che sia necessario, ulteriori elementi della pagina per trovare una corrispondenza con il selettore. Non è mai necessario definire in questo modo un id. Un id, nel contesto della specificità, ha un peso molto elevato perché rappresenta in modo univoco un elemento presente sulla pagina; un id avrà, dunque, sempre, una corrispondenza diretta con un elemento. Definire selettori di id e classe indicando anche l'elemento HTML fa anche sì che aumenti in maniera clamorosa la specificità dei selettori, rendendo necessario fare ricorso a selettori ancora più specifici o alla keyword !important per superare queste regole oltremodo specifiche.

Selettori come questo

div#widget-nav div#widget-nav-slider

possono essere semplificati così

#widget-nav #widget-nav-slider

e ulteriormente alleggeriti in questo modo

#widget-nav-slider

Tutti forniscono lo stesso risultato.

Un discorso analogo si può fare per le classi. Eliminando il riferimento all'elemento HTML, diminuisce la specificità del selettore. In questo modo possiamo usare al meglio il meccanismo della cascata per sovrascrivere, se necessario, certe regole di stile. Per esempio, invece che

li.chapter

potremmo usare

.chapter

Ancora meglio sarebbe, perché è più adatto al caso del <li>, modificare la classe applicata al <li> e avere nei CSS una cosa del genere:

.li-chapter oppure .list-chapter

Ridurre la catena del selettore a tre o meno elementi

Quando si ristruttura un CSS, usate la regola del "tre o meno": un selettore combinatore non dovrebbe presentare più di tre step per raggiungere il selettore chiave. Per esempio, prendete questo selettore assurdo:

div#blog-footer div#col2.column div.bestright p.besttitle {margin-bottom: 4px;}

Per avere tre step o meno, lo modifichiamo così:

#col2.column .besttitle {border: 1px solid #eee;}

Usare con accortezza le dichiarazioni

Il passo successivo del processo di ristrutturazione consiste nel concentrarsi sulle dichiarazioni degli stili. Quando si compie un'operazione del genere per trasformare un CSS disorganizzato in qualcosa di più gestibile, è facile porre attenzione prima di tutto ai selettori e pensare che gli stili funzioneranno comunque bene. Tuttavia, porre cura e attenzione anche alle dichiarazioni può fare la differenza quando l'obiettivo è quello di ottenere un CSS perfetto.

Figura 3 - Anatomia di una regola CSS

screenshot

Gestire al meglio l'ereditarietà

Spesso pensiamo di conoscere bene qualcosa quando in realtà non è così: l'ereditarietà nei CSS potrebbe essere uno di questi argomenti. Magari ricordate che l'ereditarietà è un concetto chiave dei CSS, ma forse non ricordate quali proprietà sono ereditate e quali no. La tabella in figura 4 mostra le proprietà più comunemente usate che vengono ereditate dagli elementi discendenti. Questi ultimi erediteranno gli stili definiti per il loro parente a meno che non vengano impostati altri stili. Oltre a queste proprietà ve ne sono altre meno comuni che vengono ereditate.

Figura 4 - Proprietà ereditate dagli elementi discendenti

screenshot

È importante tenere presenti queste proprietà quando si cerchino stili ridondanti da consolidare o eliminare. Quando aggiornate un foglio di stile, le proprietà che possono essere ereditate dovrebbero essere collocate nel CSS in modo tale che possano essere utilizzate al meglio e non ripetute. Con la giusta collocazione di queste proprietà, dichiarazioni ridondanti di stili collocate dopo potranno essere del tutto eliminate.

Rivedere e ridurre l'uso della parola chiave !important

Se il vostro CSS è pieno di ricorrenze della parola chiave !important, è venuto il momento di ridurle. Questa keyword dovrebbe essere usata solo in certe circostanze. Chris Coyer di CSS Tricks raccomanda di usarla con classi di utilità o nei fogli di stile utente.

Ma come ridurre l'uso e le ricorrenze di !important? Prima di tutto, mantenete bassa la specificità dei selettori seguendo i suggerimenti che abbiamo dato in precedenza. Poi, ricordate che, idealmente, nuovi stili non dovrebbero annullare regole precedenti, ma aggiungersi ad esse.

Ecco cosa intendo dire: se vi trovate a scrivere nuove regole di stile per annullare uno stile definito prima e poi a usare !important per superare lo stile nel momento in cui si verifica un conflitto, allora dovreste riesaminare lo stile più vecchio, valutarne bene la necessità, e poi creare nuove regole di stile che estendano gli stili originali invece che annullarli. Spiegheremo meglio questo meccanismo più avanti.

Non ripetere le regole e le dichiarazioni

Per eliminare gli stili ripetuti in un CSS, può aiutare l'approccio DRY CSS ("Don't repeat yourself") di cui abbiamo parlato nel precedente articolo. Adottare totalmente questo approccio potrebbe suonare come eccessivo e quasi draconiano, ma essere consapevoli delle ripetizioni e del perché vengono fatte organizzando tutto in gruppi è comunque un ottimo esercizio.

Come abbiamo visto l'approccio MetaCoax fornisce un metodo per modificare i vostri CSS in fasi successive per ottenere un codice più pulito e facile da gestire. Questo articolo finale descrive le ultime due fasi delle quattro previste nel processo. Alla fine tireremo le somme valutando il modo in cui è stato applicato con successo in un progetto reale.

Fase 3: snellire i selettori, raggruppare e separare

La fase 3 mira a rendere il foglio di stile ancora più leggero. Continueremo a eliminare la ridondanza ottimizzando al meglio i selettori, strutturando il codice sotto forma di moduli, creando una libreria di pattern e una guida degli stili. Questa fase presume che abbiate implementato le fasi 1 e 2, dal momento che queste modifiche aggiungono un livello di affinamento ulteriore a quelli precedenti.

Ecco quello che faremo:

  • Modularizzare ulteriormente
    • Usare nomi per gli stati degli elementi e nomi per il Javascript per le relative classi
    • Spostare tutti gli stili a un livello modulare
  • Snellire i selettori
    • Eliminare completamente i tag HTML dai selettori
    • Eliminare completamente gli id come selettori
  • Raggruppare e separare
    • Evitare ripetizioni
    • Suddividere il CSS in base a categorie
    • Prepararsi per l'uso delle media query

Modularizzare ulteriormente

Il processo di identificazione e definizione di moduli sul sito sarà probabilmente continuo, perché altrettanto probabilmente i pattern diverranno più evidenti col passare del tempo e man mano che si procede con la modularizzazione di altre parti del codice.

Fino a questo punto, abbiamo fatto un gran lavoro per ripulire i vecchi selettori e per rimpiazzarli con nuovi stili e nuovi selettori che svolgono la stessa funzione con meno righe di codice e che possono essere riusati in tutto il sito.

Ispirandoci all'approccio CSS for Grownups, sappiamo che mantenere gli stili a un livello modulare significa che essi diventano realmente portabili e riusabili, dal momento che sono legati al modulo in sé e non alla pagina, ad una sezione della pagina o al contenitore di un certo elemento. Le tecniche che vedremo da qui in avanti ci conducono a percorrere il cammino già intrapreso.

Mentre procede il lavoro di modularizzazione, ci sono alcune altre classi che dovrebbero essere create: classi per gli stati degli elementi e per il Javascript. OOCSS, SMACSS e CSS for Grownups raccomandano di assegnare a queste classi nomi che siano chiaramente denotati e identificabili per questi due scopi. In questo modo saranno più evidenti nel foglio di stile e più facili da ritrovare e aggiornare.

Nomi di classe per gli stati degli elementi

Una pratica molto interessante ricavata dall'approccio SMACSS è quella di usare nomi che indicano uno stato per le classi che definiscono, appunto, lo stato di un elemento. Le classi di stato sono fatte per stare da sole e sono tipicamente definite con un singolo selettore. Per esempio, un modulo può essere esteso attraverso specifici stati in questo modo:

.is-collapsed
.is-active
.is-error
.is-hidden

Se la regola per lo stato è fatta per un modulo specifico, si raccomanda di includere il nome del modulo nel nome della classe. Per esempio:

.is-navitem-hidden

Personalmente, trovo questa sintassi molto poco attraente. A mio parere quella che segue è più facile da impostare e consente di ritrovare più rapidamente la regola:

.navbar-is-hidden
.is-hidden-navbar

Classi specifiche per il Javascript

Nicholas Gallagher, sviluppatore straordinariamente capace, ha a suo tempo presentato una tecnica che prevede la creazione di classi specifiche per il Javascript. Raccomanda di usare certe classi solo come aggancio per gli script e di non collegare ad esse nessuno stile relativo alla presentazione nel CSS. Una classe di questo tipo, specifica per il Javascript, verrebbe così denominata:

.js-login

Snellire i selettori

Finora, abbiamo ristrutturato i selettori per renderli più efficienti e ordinati: abbiamo eliminato i qualificatori HTML dai nomi di classe e di id, abbiamo imparato che non si creano nomi di classe per l'elemento body per definire una pagina specifica, abbiamo visto che la catena dei selettori combinatori dovrebbe essere composta da tre o meno elementi. Siamo ora pronti per le ultime operazioni di pulizia. Con esse renderemo il codice ancora più ottimizzato e leggero.

Eliminare i tag HTML come selettori

Questa raccomandazione si applica agli stili che sono collegati al layout, a moduli, allo stato degli elementi o alle cosiddette skin. Non si applica invece agli stili di base o a quelli di reset. Ecco cosa tenere sempre presente: i selettori che fanno riferimento ai tag sono troppo strettamente legati alla struttura HTML perché possano essere inseriti nel contesto di un modulo o di un componente. Dunque, riguardate il vostro CSS, e se trovate ancora riferimenti a tag HTML nei selettori, fate in modo di trasformare quel selettore in una classe e agite secondo quanto suggerito in questo video.

Eliminare gli id come selettori

Allo steso modo, se ci sono #id come selettori nel foglio di stile, questi stili potrebbero essere strettamente legati al documento o ad una posizione nel documento. Significa anche che la specificità del selettore sarà troppo elevata e continuerà a incoraggiare la pratica di scrivere selettori ancora più specifici per sovrascrivere uno stile. Il CSS diventerà sempre più lungo e pesante. Non fatelo, dunque. Eliminate tutti i riferimenti agli #id.

Raggruppare e separare

L'ultima raccomandazione per mettere definitivamente ordine nel CSS e dominarne la struttura, è quella di raggruppare e mettere insieme secondo criteri logici.

Non ripetere

La forza dell'approccio DRY CSS consiste essenzialmente nell'idea del "non ripetere". Non ho trovato molte occasioni per incorporare le pratiche di questo approccio nel processo che ho chiamato MetaCoax, ma trovo molto interessanti alcuni aspetti della pratica del raggruppamento dei selettori che hanno uno stesso stile.

Per esempio, se una cosa come font-weight: bold è stata ripetuta molte volte nel foglio di stile per diversi elementi e selettori, ho individuato una situazione in cui molti dei selettori possono essere raggruppati avendo {font-weight: bold} come stile. Tuttavia, applicherei questa pratica come l'ultima di una serie di tecniche e solo una volta che i selettori siano stati del tutto ottimizzati.

Suddividere il CSS in base a categorie

Nella fase 2, abbiamo imparato a creare nel nostro foglio di stile una suddivisione in categorie, come suggerito dall'approccio SMACSS. È ora il momento di fare un passo avanti e di suddividere quelle sezioni in fogli di stili separati: base.css, layout.css, module.css, state.css e theme.css.

Devo ammettere di non essere molto favorevole a questa pratica di separare il CSS in più file, perché non mi piace andare a cercare in più posti per ritrovare gli stili che mi interessano. Tuttavia, può diventare una pratica utile se vi pare di sprecare troppo tempo facendo lo scrolling in documenti eccessivamente lunghi.

Prepararsi per l'uso delle media query

Nel momento in cui si prevede di adottare un design responsivo, l'approccio SMACSS offre un altro suggerimento molto utile per gestire le media query. Invece di raggrupparle alla fine del foglio di stile, Jonathan Snook suggerisce di aggiungere le media query agli stili del layout e dei moduli a cui sono applicate, collocando dunque le media query intorno agli stati del modulo o del layout. Sì, la dichiarazione della media query sarà fatta probabilmente più volte, ma tutta l'informazione relativa al modulo sarà tenuta insieme in un unico punto, cosa che facilita di molto i test su quel modulo specifico.

Fase 4: condividere

La fase finale di questo processo di ristrutturazione e di tutte le metodologie scalabili (specie di CSS for Grownups) è quella di creare una libreria di stili per moduli (detta anche libreria di pattern) e una guida di stile.

Una libreria di pattern è una raccolta di tutti i vari moduli e componenti presenti sul sito. Una guida di stile, invece, è un documento che illustra l'uso appropriato di ciascuno dei componenti nel contesto del sito e i modi con cui i componenti interagiscono. La guida di stile dovrebbe comprendere tutti gli elementi che possono essere rintracciati sulle varie pagine e gli stili che corrispondono a ciascun elemento. L'obiettivo principale nella creazione di queste due risorse è quello di avere più consistenza nella gestione del sito man mano che esso evolve e viene modificato.

Questa è la fase "finale" del progetto, ma non viene svolta per ultima. Iniziate a lavorarci sin dall'inizio del progetto. La libreria di pattern e la guida di stile non dovrebbero essere portate a termine alla fine come se fossero un'aggiunta tardiva all'intero progetto. Sono strumenti essenziali.

Ecco quello che faremo:

  • Creare una libreria di pattern
  • Creare una guida di stile

Librerie di pattern

La costruzione di una libreria di pattern è il metodo con cui potrete creare scenari per il test degli stili in un ambiente del tutto neutrale. La creazione di tale libreria dovrebbe avvenire contestualmente agli aggiustamenti effettuati sul codice. Ecco alcuni suggerimenti per iniziare:

  1. Identificate i singoli elementi e componenti che appariranno sul sito. Prendete nota dei colori primari per il testo, i titoli, i link, i pulsanti.
  2. Iniziate a creare gli stili per gli elementi fondamentali della pagina: titoli, link, tabelle, blocchi di citazioni, liste ordinate e non ordinate, form.
  3. Applicate gli stili ai moduli/componenti indipendentemente dalla pagina su cui appariranno: renderete così la pagina realmente composta da moduli indipendenti.
  4. Create gli stili per i componenti che vanno a sovrapporsi agli stili di base, come il box per la ricerca, la navigazione a breadcrumb, pulsanti con stili particolari, variazioni dei singoli moduli. Includete gli stili per le interazioni: hover, focus, active.
  5. Inserite tutto il codice e gli snippet di codice su un servizio in cui sarà facile accedere ai pattern e gestirli.

La parte più problematica nella creazione di una libreria di pattern è capire come strutturarla. Ci sono sul web ottimi esempi a cui ispirarsi. Un esempio eccellente è la libreria di pattern di MailChimp. PatternPrimer è invece un grande esempio di creazione di snippet di codice indipendenti dal contesto della pagina (è disponibile anche su GitHub) ed è specialmente utile quando si lavora con un approccio mobile-first nel responsive design. Il servizio Pears Pattern è come una mini-libreria basata su WordPress per inserire e gestire pattern comuni di markup e stili in una raccolta di esempi indipendente anch'essa dal contesto.

Guide di stile sul web

Ora che avete i componenti del sito, è il momento di creare la guida di stile che illustra come tutto funziona nel complesso sul sito, e non solo a livello di pagina singola. Creando una guida di stile con gli stili acquisiti dalla libreria di pattern, potrete spezzare il circolo vizioso in cui si cacciano tanti siti, con CSS sviluppati da molte persone che non avevano la minima idea di quello che avevano fatto gli sviluppatori precedenti perché nulla era stato documentato.

È importante, tuttavia, essere consapevoli di alcuni potenziali problemi delle guide di stile. Non dovrebbero essere troppo rigide, come i tradizionali manuali per gli standard grafici che troppo spesso spengono la creatività e attivano un modo di pensare troppo burocratico. Le guide di stile dovrebbero essere entità vive, flessibili. Dovrebbero essere il punto di contatto tra designer e sviluppatori all'interno del team.

Vale la pena aggiungere una considerazione: il modo più facile per evitare che la creazione di una guida di stile diventi l'ennesimo onere da portare stancamente a termine è quello di crearla mentre si lavora alla ristrutturazione del CSS. Anna Debenham, nell'articolo Front End Style Guides, offre questi suggerimenti:

  1. Aggiungete il layout alla fine e inserite i componenti al posto giusto. Ogni layout proposto sul sito potrebbe essere presentato in un documento separato.
  2. Documentate il vostro processo di codifica: le convenzioni usate nell'assegnare i nomi, il perché si siano raggruppati gli stili in un certo modo, la classificazione dei componenti, etc.
  3. Incoraggiate la partecipazione da parte del team e di tutti gli sviluppatori del front-end per assicurare un risultato ottimale a partire dalla condivisione.

Un consiglio aggiuntivo: mantenete la guida breve, facile da leggere, come la guida alla gestione degli asset di brand curata da MailChimp. Non c'è bisogno di scrivere un tomo, più lunga sarà la guida meno saranno le possibilità che venga letta.

La guida di stile del sito Starbucks.com è un ottimo modello, molto ben organizzata e documentata, fornisce un eccellente esempio di come si debba strutturare una guida diffusa sul web. La Kalei Style Guide genera una documentazione per i CSS in stile Twitter Bootstrap: vale la pena darci un'occhiata. Anna Debenham ha messo insieme una fantastica collezione di altre guide di stile.

Con una buona guida, finiscono i tempi in cui gli stili non erano documentati mentre si realizzava il sito, lasciando ad ogni sviluppatore il compito gravoso di capire come ottenere gli stessi esiti per conto proprio. È vero che per siti molto grandi e complessi con diverse opzioni di layout una guida di stile può rappresentare uno sforzo enorme, ma ne varrà la pena se si pensa a quanto in futuro potrà facilitare la vita agli sviluppatori.

Un'applicazione di successo dell'approccio MetaCoax

Le teorie che crescono intorno a dei processi sono fantastici esercizi mentali, ma le idee migliori sono quelle che possono essere messe in pratica. Ho sviluppato l'approccio MetaCoax combinando le migliori pratiche di diversi sistemi e l'ho testato su un sito che aveva un CSS disordinatissimo di oltre 7500 righe. Come è andata?

  • Il numero totale di righe di codice è stato ridotto a 2500
  • Sono stati eliminati la maggior parte degli stili in linea e degli elementi non semantici
  • Sono state implementate tutte le migliori pratiche oggi in auge
  • È stata realizzata una griglia, eliminando 327 ricorrenze della proprietà width e 738 ricorrenze della proprietà margin
  • Sono stati eliminati anche
    • 1259 ricorrenze di div# e div
    • 936 stili che contenevano body#
    • 126 ricorrenza della parola chiave !important
    • 189 ricorrenze della proprietà margin-top e 112 di margin-bottom

Il sito è ora anche pronto per il futuro. Tutto è stato ottenuto senza apportare nessun cambiamento al sito dal punto di vista visuale!

Gli approcci scalabili e modulari sono vincenti

Abbiamo dunque visto una serie di princìpi, pratiche e un intero processo per ristrutturare i CSS. Aiuteranno tutto il team di sviluppo e potenzialmente possono modificare il flusso di lavoro di un intero dipartimento che lavori al sito web. Anche se non seguirete il processo, spero che ora abbiate il coraggio di guardare ad ogni processo di aggiornamento dei CSS con maggiore fiducia. È tempo di agire, amici, e di ristrutturare i vostri fogli di stile!

Ti consigliamo anche