Sass estende il linguaggio CSS attraverso una serie di funzionalità e costrutti che costituiscono un semplice linguaggio scripting il quale prende il nome di Sass Script. Quest’ultimo consente di utilizzare appunto variabili, operatori, funzioni e altri costrutti sintattici che vengono poi interpretati dal transpiler (compilatore che trasforma il codice sorgente scritto in un linguaggio in un altro linguaggio) nel momento in cui genera i file CSS. Nel resto di queste lezioni faremo spesso riferimento a Sass Script utilizzando semplicemente il nome Sass.
Le variabili in Sass
Le variabili rappresentano senza ombra di dubbio una delle funzionalità più utili e interessanti di Sass che rendono immediatamente evidente quanto sia vantaggioso usare un simile strumento al posto del semplice linguaggio CSS. Consentono infatti di scrivere del codice che risulta più semplice da mantenere, visto che si può evitare in questo modo di dover riscrivere uno stesso valore in diverse parti di uno o più fogli di stile. È vero comunque che al linguaggio CSS è stato aggiunto il supporto alle variabili, meglio note come custom properties, che funzionano ormai sulla maggior parte dei browser moderni, ma bisogna sottolineare delle differenze fondamentali fra le custom properties del CSS e le variabili di Sass. Un vantaggio delle prime è rappresentato dal fatto che non c’è bisogno di utilizzare un preprocessore ed è possibile accedere e modificare il loro valore direttamente dal codice scritto in Javascript. Le variabili presenti in Sass sono invece dei semplici contenitori in cui conservare dei valori. Nel momento in cui vengono generati i file CSS il compilatore provvede a sostituire le variabili con i loro valori. Analizzando i file CSS creati non è quindi presente nessun elemento che può portare un osservatore a stabilire se si sia usato un preprocessore come Sass o meno. Le variabili in Sass sono identificate dal carattere ‘$’ il quale viene anteposto al nome della variabile stessa che, in linea generale, può contenere qualsiasi carattere alfanumerico, i caratteri ‘_’ (underscore) e ‘-‘ (hyphen) oppure alcuni caratteri speciali (!”#$%&’()*+,./:;<=>?@[]^{|}~) o spazi purché preceduti dal carattere di escape ‘\’ (backslash). Bisogna però prestare particolare attenzione all’uso dei caratteri ‘_’ (underscore) e ‘-‘ (hyphen) che possono essere usati senza distinzione fra i due per problemi di compatibilità con versioni precedenti di Sass. Ciò vuol dire che quelle che possono sembrare due variabili distinte, come $primary-color e $primary_color, sono in realtà la stessa variabile. Chiariamo quest’ultimo concetto con un semplice esempio.
/* file style.scss */
$primary-color: aquamarine;
$primary_color: aliceblue;
$text-color: darkslateblue;
p {
background-color: $primary-color;
color: $text_color;
}
Lanciando node-sass non visualizzeremo nessun messaggio di errore e il file CSS generato sarà il seguente.
/* file style.css */
p {
background-color: aliceblue;
color: darkslateblue;
}
I tipi di dato presenti in Sass
A una variabile è possibile assegnare vari tipi di valori. In particolare Sass supporta 8 diversi tipi di dato:
- null
- boolean
- number
- string
- color
- lista di valori
- mappa di valori
- riferimento a una funzione
Vediamo rapidamente degli esempi di alcuni dei tipi di dato elencati sopra.
I colori
A ogni variabile è possibile assegnare le stesse espressioni supportate dal linguaggio CSS per rappresentare un colore. Quelle riportate nell’esempio sottostante sono quindi tutte alternative valide.
/* file style.scss */
$color_1: wheat;
$color_2: #456789;
$color_2_1: #456789bb;
$color_3: rgb(36, 54, 88);
$color_4: hsl(120, 24%, 45%);
$color_5: rgba(5, 147, 172, 0.543);
$color_6: hsla(71, 79%, 55%, 0.63);
Il tipo di dato Stringa in Sass
In SassScript la sintassi valida per le stringhe prevede l’uso di virgolette doppie (") o singole ('). È però possibile creare una stringa anche senza virgolette.
/* file style.scss */
$default-font: 'Segoe UI';
$code-font: "Courier New";
$default-position: relative;
p {
position: $default-position;
font-family: $default-font, Tahoma, Geneva, Verdana, sans-serif;
}
code {
font-family: $code-font, Courier, monospace;
}
Le liste in Sass
Le liste costituiscono un altro tipo presente in Sass. Si tratta di una serie di valori separati da virgole o spazi.
/* file style.scss */
$code-font: 'Courier New', Courier, monospace;
$default-padding: 10px 8px;
code {
font-family: $code-font;
padding: $default-padding;
}
È possibile combinare i due separatori per creare delle sottoliste. (lista di liste)
/* file style.scss */
$transition: opacity .5s linear, transform .8s ease-out;
$size: 48px;
$border-radius: 4px;
.square {
background-color: lightseagreen;
border-radius: $border-radius;
width: $size;
height: $size;
transition: $transition;
opacity: 1;
}
Nell’esempio riportato sopra $transition è una lista contenente due altre liste. La lista esterna usa una virgola come separatore mentre le due liste annidate utilizzano uno spazio. Per questioni di leggibilità è possibile usare delle parentesi tonde per racchiudere una lista.
/* file style.scss */
$transition: (opacity .5s linear), (transform .8s ease-out);
Le mappe in Sass
Le mappe sono invece delle strutture dati usate per mantenere coppie di chiave-valore. La sintassi per le mappe prevede che queste vengano racchiuse in parentesi tonde e le coppie ‘chiave: valore’, in esse contenute, devono essere separate da virgole. Le chiavi della mappa possono essere di qualsiasi tipo di dato (anche un’altra mappa). Le mappe sono per lo più manipolate usando le funzioni predefinite di SassScript di cui parleremo nelle prossime lezioni.
/* file style.scss */
$my_map: (small: 12px, medium: 16px, big: 20px);
$small-value: map-get($my_map, small);
p {
font-size: $small-value;
}
Nell’esempio riportato sopra abbiamo creato una mappa contenente tre differenti valori. Grazie alla funzione predefinita map-get($map, $key) recuperiamo il valore corrispondente alla chiave ‘small’ che assegniamo alla proprietà font-size di un paragrafo attraverso la variabile $small-value.
/* file style.css */
p {
font-size: 12px;
}
Interpolazione delle variabili in Sass
Una delle funzionalità più interessanti presenti in Sass Script è l’interpolazione delle variabili che permette di creare i nomi delle proprietà e dei selettori in maniera dinamica. Per usare l’interpolazione basterà racchiudere il nome di una variabile fra parentesi graffe a cui si antepone il carattere ‘#’ (#{$nome-della-variabile}). Vediamo un semplice esempio.
/* file style.scss */
$element: span;
$number-of-items: 74;
#{$element}::after {
content: "Solo #{$number-of-items} pezzi disponibili";
}
Verrà quindi generato il seguente file CSS.
/* file style.css */
span::after {
content: "Solo 74 pezzi disponibili";
}
Visibilità delle variabili in Sass
In Sass la visibilità di una variabile è limitata al blocco in cui è definita. Le variabili definite al di fuori di un gruppo di dichiarazioni sono accessibili all’interno di qualsiasi regola.
/* file style.scss */
$global: 200px;
.foo {
$a: 10px;
border-radius: $a; // 10px
width: $global; // 200px
}
.bar {
border-radius: $a; // Error: Undefined variable
width: $global; // 200px
}
Nell’esempio riportato sopra $a è stata definita nel blocco di dichiarazioni della classe foo per cui non è accessibile all’interno della regola per la classe bar. Provando a lanciare node-sass verrebbe mostrato a video un messaggio di errore il quale ci avvisa che non è possibile determinare il valore della variabile $a all’interno del blocco di dichiarazioni della classe bar. Se volessimo rendere $a accessibile anche nelle altre regole potremmo usare il modificatore !global come mostrato sotto.
/* file style.scss */
$global: 200px;
.foo {
$a: 10px !global;
border-radius: $a;
width: $global;
}
.bar {
border-radius: $a;
width: $global;
}
In questo caso verrebbe generato il file style.css senza alcun problema.
/* file style.css */
.foo {
border-radius: 10px;
width: 200px; }
.bar {
border-radius: 10px;
width: 200px; }
Come vedremo nelle prossime lezioni, in Sass è possibile usare delle regole annidate. In questo caso le regole per la visibilità di una variabile restano comunque le stesse. Le regole annidate hanno accesso alle variabili definite all’esterno. Bisogna prestare attenzione ad alcuni casi particolari. Per esempio se all’interno di un blocco di dichiarazioni di una regola annidata si modifica una variabile definita ad un livello superiore, il valore di quest’ultima cambia anche per le altre regole successive. Cerchiamo di capire meglio quanto appena esposto con un esempio.
/* file style.scss */
$a: 2em;
div {
$b: 500px;
width: $b; // 500px
.foo {
$b: 200px; // sovrascrive il valore della variabile $b
$c: 250px;
$d: 10px !global;
width: $c; // 250px
height: $b; // 200px;
font-size: $a; // 2em
border-radius: $d; // 10px
}
.bar {
border-radius: $d; // 10px
height: $b; // 200px
}
// $b assumerà il nuovo valore definito in .foo,
// ovvero 200px
height: $b; // 200px
}
Nella classe foo abbiamo mutato il valore di $b. Tale modifica si riflette anche per il valore della proprietà height della regola del div in cui è annidata la regola per gli elementi della classe foo.
/* file style.css */
div {
width: 500px;
height: 200px; }
div .foo {
width: 250px;
height: 200px;
font-size: 2em;
border-radius: 10px; }
div .bar {
border-radius: 10px;
height: 200px; }