CSS incapsulato per lo sviluppo a componenti | Antreem
Vai al blog

CSS incapsulato per lo sviluppo a componenti

di lettura
Massimo Artizzu
thumbnail

Abbiamo scelto di parlare di CSS incapsulato perché, ogni giorno, riscontriamo sempre di più l’esigenza di programmare in maniera scalabile, modulare. Servono quindi pratiche strutturate, per permettere di sviluppare progetti di ogni tipo seguendo percorsi chiari e adattabili a ogni esigenza

Da oltre 20 anni, il linguaggio CSS è stato un punto fondamentale per lo sviluppo di siti e applicazioni web/ibride mobile, andando a definire l’aspetto di presentazione dell’interfaccia, che insieme a quello di contenuto (delegato a HTML) e di interattività (JavaScript) costituiscono le parti fondamentali del front-end di un’applicazione o un sito.

CSS è sempre stato un linguaggio dichiarativo, di semplice utilizzo e dai risultati immediatamente visibili. Ma essere semplice non comporta che sia anche facile. In particolare, lo sviluppo della parte CSS presente molto velocemente problemi di scalabilità e mantenibilità del codice, che rischiano di portare al blocco del progetto in assenza di regole e linee guida da seguire.

Sopravvivere con CSS

Durante gli anni si sono affermati una serie di principi di base per lo sviluppo del fogli di stile CSS, tutti rivolti a risolvere i principali problemi che gli sviluppatori web hanno evidenziato nel corso degli anni. Tra i più affermati, i principi OOCSS, SMACSS ed il più noto BEM.

Concentrandosi su quest’ultima convenzione, siamo naturalmente portati a sviluppare le nostre applicazioni a “componenti” (i “blocchi” della sigla), cioè elementi interattivi indipendenti all’interno dell’interfaccia. Se volessimo creare un selettore di data (date-picker), il relativo foglio di stile avrebbe un aspetto di questo tipo:

.date-picker { ... }
.date-picker__date-head { ... }
.date-picker__day { ... }
.date-picker__day--current { ... }
...

E verrebbe usato con una struttura HTML di questo tipo:

<table class="date-picker">
  <thead><tr>
    <th class="date-picker__date--head">Lun</th>
    ...
  </tr></thead>
  <tbody>
    <tr><td class="date-picker__day">28</td>...</tr>
    ...
  </tbody>
</table>

Si noti l’uso esclusivo di classi nelle dichiarazioni di stile, con nomi a volte molto lunghi e quindi poco leggibili. Si tratta di un pegno da pagare per avere del codice CSS mantenibile, riutilizzabile e dagli effetti limitati al componente che si vuole stilizzare. L’obiettivo, infatti, è quello di creare una nomenclatura di classi CSS che siano possibilmente uniche tra tutte quelle definite all’interno della pagina.

L’approccio dei Web Component

Tuttavia negli ultimi anni c’è stato lo sforzo di risolvere l’annoso problema della “globalità” delle regole di stile CSS. La spinta decisiva è arrivata dall’ideazione dei Web Components, un insieme di API che consentono la creazione di elementi HTML “custom”, con una propria funzionalità interna, un proprio “ciclo di vita” e soprattutto un proprio foglio di stile, la cui influenza rimane isolata (“incapsulata”, nel gergo) all’interno dell’elemento definito e non avrà così effetti sul resto dell’applicazione.

In base a questa filosofia di sviluppo, l’obiettivo non sarà più creare un foglio di stile globale per l’applicazione, costruendolo pezzo per pezzo e stando attenti a non avere parti sovrapposte, ma creare tanti stili limitati al proprio componente e che solo nell’insieme daranno una rappresentazione completa all’applicazione.

Il risultato sarà di avere fogli di stile piccoli e modulari, come già eravamo abituati con BEM, ma con una nomenclatura molto più leggera. Questo deriva dal fatto che non abbiamo bisogno di creare classi dal nome lungo e (sperabilmente) univoco, perché le dichiarazioni del nostro modulo avranno influenza solo per il nostro componente.

Così, per riprendere l’esempio precedente, il foglio di stile risultante potrebbe essere ridotto a questo:

table { ... }
th { ... }
td { ... }
.current { ... }

E anche la struttura HTML ne risulterebbe di gran lunga alleggerita:

<table>
  <thead><tr>
    <th>Lun</th>
    ...
  </tr></thead>
  <tbody>
    <tr><td>28</td>...</tr>
    <tr>...<td class="current">4</td>...</tr>
    ...
  </tbody>
</table>

Quello che era considerato tabù fino a poco tempo fa, come creare selettori composti da giusto un nome di tag, o usare nomi di classe brevi e generici, diventano nuovamente possibile grazie all’incapsulamento degli stili all’interno del componente. Anche pratiche come usare id nei selettori o il modificatore !important possono avere ora un senso.

Il fatto è che lo sviluppo a componenti ci consente di concentrare e di limitare la nostra attenzione unicamente al componente che stiamo sviluppando, e l’incapsulamento degli stili è il tassello finale a questo modo di sviluppare. Non avremo più, quindi, una separazione logica e fisica tra template, funzionalità e presentazione, ma tutti questi aspetti verranno considerati come un’unica entità, cioè il componente.

Stile locale e tema globale

Quel che può apparire spiazzante con questo tipo di sviluppo è che sviluppare un look and feel coerente per l’applicazione non appare immediato. Il fatto è, però, che è bene abituarsi ad adottare uno sviluppo delle interfacce che comporta la minima intrusione di stili dall’applicazione nei componenti.

Tuttavia, anche riducendo al minimo la necessità di stilizzare i componenti, questa non scompare del tutto. Quello che deve essere chiaro, però, è che è il componente ad avere il controllo di ciò che può o non può essere stilizzato dall’esterno. Il componente, cioè, deve offrire un’interfaccia parametrica per essere stilizzato all’interno dell’applicazione: ad esempio, esporre un parametro per decidere il colore di sfondo, ma non uno per determinare la spaziatura del testo.

Tale interfaccia può essere esposta tramite semplici attributi del componente, oppure tramite le custom properties di CSS. Altre soluzioni sono ancora al vaglio degli organi di governance dello standard CSS.

Componenti e framework

Il framework Polymer, che si appoggia esplicitamente ai Web Component, propone esplicitamente questo approccio consentendo di definire le suddette parti in un unico file (con il caveat per cui dalla versione 3 l’importazione di componenti custom cambierà dall’uso degli HTML imports ai moduli ES2015).

Parimenti Vue.js – sebbene non nativamente basato sui Web Component – consente di fare altrettanto. Invece le linee guida di Angular suggeriscono una nomenclatura consistente tra i file che definiscono un componente, indicando di dedicare una cartella per ognuno di essi.

L’altro “peso massimo” tra le librerie di sviluppo front-end, cioè React, è essenzialmente “non opinionato” riguardo l’adozione degli stili, per cui gli sviluppatori sono liberi di usare ciò che vogliono. Questo ha causato la proliferazione di pacchetti per la stilizzazione dei componenti, come Styled Components, CSS Modules e così via, ma tutti basati sul concetto di incapsulamento degli stili.

Cosa ci aspetta

A detta della comunità dello sviluppo web, l’approccio dello stile incapsulato è un passo nella giusta direzione, e solleva i programmatori dall’onere di emulare tale metodologia con BEM o altre convenzioni. Meno regole da seguire significa anche menò possibilità di commettere errori.

In definitiva, la strada futura è chiara ma riserverà ulteriori novità per lo sviluppo di applicazioni web (o basate su tecnologie web) sempre più complesse.

Massimo Artizzu
Scritto da
Massimo Artizzu
Formato in Matematica, ma adottato professionalmente nella programmazione, un pallino avuto sin da piccolo. Amante di enigmi e origami, giocatore di rugby per diletto.