BazarJS: Pre (e post) processori CSS

Continua la serie di articoli BazarJS prendendo una breve pausa (digestiva, se vogliamo) dal mondo Javascript, per affrontare invece il tema stylesheets, non meno importante. Forti della nostra esperienza con Sass, tenteremo di esaminare le principali alternative Javascript disponibili (Less.js e Stylus). Vale la pena cambiare preprocessore?

Per concludere, daremo un occhio ad un insieme di tool cresciuti in popolarità nel 2014 accomunati invece da meccanismi di postprocessamento.

Tempo di lettura: 8 minuti

Sappiamo bene di come il CSS abbia i suoi limiti, e conosciamo anche l'inevitabile lentezza con la quale lo standard del linguaggio evolve e viene implementato sui browser. L'idea di un preprocessore CSS nasce proprio dall'osservazione di queste problematiche, e dal desiderio di porvi rimedio: invece di scrivere CSS, per realizzare fogli di stile sfruttiamo un nuovo metalinguaggio più potente ed espressivo, in grado di essere compilato in semplice CSS da poter includere nelle nostre pagine web.

Domanda a bruciapelo: da quanto tempo parliamo ormai di preprocessori CSS? Otto anni. Non poco, nel nostro mondo. Sass, il primo progetto ad implementare questa idea, viene rilasciato proprio nel 2007.

Inizialmente il progetto è stato supportato soprattutto all'interno della nicchia degli sviluppatori Ruby — gli hipster dell'epoca, se vogliamo — ma lentamente ed inesorabilmente ha allargato i suoi confini diventando uno strumento conosciuto e sfruttato praticamente su qualsiasi stack tecnologico, ed ha regnato incontrastato e senza l'ombra di un competitor per almeno 3 anni.

Il 2010 ha visto la nascita di alcune alternative interessanti, scritte guarda caso proprio in Javascript. Facendo la nostra solita comparazione di numeri, possiamo renderci conto di come siano progetti di tutto rispetto e assolutamente comparabili in termini di seguito ed interesse generato:

Sass

Stylus

less.js

In cosa si differenziano?

Beh, partiamo dalle somiglianze. Tutti e tre i linguaggi, seppur con qualche differenza, supportano:

  • Scripting attraverso variabili, funzioni, iteratori e condizionali;
  • Mixins;
  • Concatenazione inline di file secondari attraverso @import;
  • Nesting dei selettori CSS;
  • Funzioni matematiche e di gestione dei colori e dei tipi base;

Less.js, a differenza di Sass e Stylus, non supporta:

  • Strutture hash;
  • La possibilità di scrivere codice con una sintassi in significant-whitespace;
  • Selector inheritance tramite la direttiva @extend, utile per ereditare regole CSS da un selettore senza provocare duplicazione di codice;

Tutti e tre i progetti sono ampiamente supportati dai principali task runner (es. gulp-stylus, gulp-less e gulp-sass), e sono in grado di generare source-maps.

Veniamo al capitolo performance. Sass, principalmente a causa di Ruby, è sicuramente il preprocessore più lento, e di molto. La discussione però non finisce qui: gli sforzi del creatore stesso di Sass Hampton Catlin, hanno portato alla luce nel 2012 libsass, una completa riscrittura in C++ del motore Sass, capace di ridurre di un ordine di grandezza i tempi di compilazione, portandoli addirittura al di sotto dei suoi competitor Javascript.

Nel 2014, i team di Sass e libsass hanno concordato di attendersi a vicenda prima di proseguire il rilascio di nuove funzionalità del linguaggio. Una mossa che ha portato in breve tempo ad una parità quasi completa a livello di features: l'elenco delle (poche) incompatibilità ad oggi restanti tra i due motori è ben documentato all'interno del progetto Sass Compatibility.

Come era facile aspettarsi, il rilascio di libsass ha permesso un ulteriore crescita del linguaggio in ambienti che fino a quel momento non potevano permettersi l'introduzione di un runtime Ruby. Ad oggi, esistono librerie binding per libsass in tutti i principali linguaggi, compresi ovviamente Ruby e Node.js.

Less.js e Stylus, a differenza di Sass, possono permettere di effettuare lo step di precompilazione direttamente lato browser, evitando dunque la necessità di un tool esterno.

Transpilers e post-processori alla riscossa

Per completare la panoramica sull'attuale proposta di strumenti pensati per migliorare la qualità di scrittura dei fogli di stile, abbiamo i cosiddetti post-processori. PostCSS è il cappello sotto al quale è nata la maggioranza di questi tool: una libreria Javascript made in Twitter in grado di permettere in maniera estremamente semplice il parsing di file CSS, la modifica dei suoi nodi e la produzione di nuovi file CSS, completi di source-maps.

In questo caso non si tratta dunque di inventare nuovi metalinguaggi, ma di continuare a scrivere regolare CSS, “aumentando” in vario modo il risultato finale tramite uno step di compilazione.

Gli esempi più popolari in questo senso?

  • Autoprefixer permette di scrivere il proprio CSS senza preoccuparsi dei vendor-prefixes. Questi verranno automaticamente aggiunti sulla base di una selezione della popolazione di browser che si intende supportare, attingendo agli ultimi dati disponibili su caniuse.com.

  • cssnext, in grado di permettere già da oggi la scrittura di file CSS4, comprendenti quindi i comportamenti avanzati già standardizzati e simili a quelli presenti nei vari preprocessori attuali: variabili, espressioni calc(), media queries semantiche, selettori custom, etc. Lo step di compilazione si occupa di riprodurre nella sintassi CSS3 il medesimo comportamento descritto.

La scelta

Cantiere arriva da una lunga esperienza con Sass — recentemente abbiamo addirittura “formalizzato” la nostra modalità di strutturazione di un progetto Sass attraverso il rilascio di BEMO.

Beh, l'analisi effettuata non ha evidenziato alcun motivo pratico per il quale potrebbe essere vantaggioso spostarci su un preprocessore alternativo.

In aggiunta a questa sostanziale “parità” in termini di feature, mi sento però di portare un punto in più a favore di Sass per l'approccio al rilascio di nuove funzionalità da parte del team Sass, ben riassunto nelle parole di Hugo Giraudel:

What I do like with Sass is its conservative approach to CSS. Sass’s design is based on strong principles: much of the design approach comes naturally out of the core teams’ beliefs that a) adding extra features has a complexity cost that needs to be justified by usefulness and, b) it should be easy to reason about what a given block of styles is doing by looking at that block alone.

Also, Sass has a much sharper attention to detail than other preprocessors. As far as I can tell, the core designers care deeply about supporting every corner-case of CSS compatibility and making sure every general behavior is consistent.

Less.js è attualmente il sistema con minori capacità di scripting. Per chi si trovasse oggi a scegliere per la prima volta quale linguaggio provare, il consiglio che mi sentirei di dare sarebbe quindi quello di concentrarsi su Sass o Stylus, a seconda dell'ambiente di riferimento (Ruby o Javascript). Sono progetti molto simili tra di loro sia dal punto di vista di funzionalità offerte che di sintassi, dunque anche un eventuale switch tra i due sistemi non sarebbe assolutamente drammatico.

Tornando a Sass, abbiamo avuto modo di testare l'engine libsass su diversi progetti in produzione per diversi mesi ormai, senza osservare particolari problemi o comportamenti anomali rispetto al suo fratello più maturo. Ci sentiamo quindi di consigliarlo, e siamo in attesa di una soluzione che permetta di sfruttarlo anche all'interno di Sprockets, l'asset-pipeline di Rails.

Il progetto cssnext è sicuramente interessante: almeno in teoria, l'idea di poter scrivere utilizzando CSS4 (ovvero uno standard) invece che investire in metalinguaggi alternativi ha il suo senso, e offrirebbe una garanzia in più di non vedere il proprio lavoro “morto” nel giro di qualche anno. Nella pratica però, nonostante i molti miglioramenti rispetto al CSS3, continua ad essere totalmente assente il concetto di scripting, fondamentale su progetti frontend mediamente complessi.

Per quanto riguarda la gestione dei prefissi vendor dei browser, Autoprefixer si è rivelato come la migliore soluzione disponibile, di gran lunga superiore all'utilizzo di mixin in stile Compass o Bourbon, che costringono ad un maggiore mantenimento nel tempo. Abbiamo sfruttato Autoprefixer con grande successo in congiunzione con Sass sia all'interno di applicativi Rails (attraverso autoprefixer-rails), sia su progetti client-side (con gulp-autoprefixer), e fa parte ormai della nostra toolchain di riferimento.

È tutto… prossima puntata? Preprocessori Javascript!

La prossima settimana continueremo a parlare di preprocessori, ma in un differente contesto, quello Javascript. Daremo un occhio alle principali alternative presenti: CoffeeScript, ECMAScript 6 e TypeScript.

Seguici su Twitter o tramite feed RSS per rimanere aggiornato sulla prossima uscita!

Hai trovato questo post interessante?Scopri chi siamo

Made with Middleman and DatoCMS, our CMS for static websites