Usare le mappe per gestire font e colori con SASS

Sono sempre alla ricerca di nuovi metodi per organizzare ed ottimizzare il mio workflow e pongo sempre molta attenzione alla leggibilità del CSS che vado a scrivere, soprattutto nel file di configurazione del progetto.

SASS oltre alle variabili ci mette a disposizione mappe e liste, che sono di fatto degli array e con questa serie di post voglio introdurvi l'approccio che seguo nella configurazione di un progetto per quanto riguarda tipografia, colori e media queries.

Le variabili in SASS trovo che siano particolarmente indicate quando si devono gestire valori diciamo singoli, come per esempio il valore del gutter o del border-radius globale, ma quando abbiamo da gestire gruppi di valori diventano un pò troppo pesanti da leggere secondo me.

Facciamo prima una brevissima distinzione tra liste e mappe in SASS.

Le liste sono una sequenza di valori, separati da virgole o spazi:

$lista: (
    valore1,
    valore2
);

mentre le mappe sono coppie di chiave e valore separati da virgole:

$mappa: (
    chiave1: valore1,
    chiave2: (
        chiave3: valore3
    )
);

Configurazione

Quando parliamo di colori è facile andare in crisi con i nomi, soprattutto quando dobbiamo gestire gradazioni diverse di un colore specifico e spesso si finisce per non seguire una logica consistente tra i vari progetti.

Chiaramente non è che utilizzare le mappe vuol dire automaticamente non commettere più errori di assegnazione dei nomi per i nostri colori.

Iniziamo quindi ad impostare la nostra mappa dei colori utilizzando il nome di variabile $colors e inserendo i primi due colori, bianco e nero:

$colors: (
    black: #000,
    white: #fff
);

A questo punto vorrei fare una piccola parentesi su un paio di best practice che seguo quando imposto questa mappa.

Regola 1

Se il colore ha delle gradazioni di luminosità utilizzare sempre le stesse parole chiave, come per esempio:

blue: (
    base: #3498db,
    dark: #135987,
    light: #6EC5FF
)

Regola 2

In alcuni casi se il progetto prevede più gradazioni di un colore lo specifico come hsl (hue, saturation, lightness) dove "l" è anche il nome che utilizzo per la chiave, questo approccio è particolarmente comodo per i grigi:

grey: (
    10: hsl(0,0,10),
    20: hsl(0,0,20),
    …
)

Detto questo una volta che abbiamo completato la compilazione della nostra mappa di colori e ci ritroviamo con un qualcosa del genere

$colors: (
    black: #000,
    white: #fff,
    blue: (
        base: #3498db,
        dark: #135987,
        light: #6EC5FF
    ),
    grey: (
        10: hsl(0,0,10),
        20: hsl(0,0,20),
        30: hsl(0,0,30),
        40: hsl(0,0,40),
        50: hsl(0,0,50)
    )
);

dobbiamo capire come estrarre questi dati per poterli richiamare nel nostro progetto.

Funzione

Essendo questo tipo di dato applicabile in vari contesti la scelta più logica è quella di creare una funzione che ritorni il valore corrispondente ad una specifica chiave, quindi la funzione la chiameremo get-color e il parametro in ingresso sarà il nome del nostro colore e opzionalmente il nome della mappa di colori (in modo da rendere questa funzione più flessibile):

@function get-color( $name, $map: $colors ) {} 

La prima cosa che possiamo notare riguardando la nostra mappa è che abbiamo a che fare con due tipi di dati differenti, uno semplice:

black: #000 

e uno composto:

blue: ( default: #3498db ) 

Potremmo chiaramente creare due funzioni separate, per gestire le due tipologie di dato ma SASS ci mette a disposizione un sistema di @if @else che ci consentirà di verificare all'interno della nostra funzione la tipologia di dato in ingresso.

Avendo un solo parametro in ingresso il valore del colore possiamo specificarlo in due modi:

get-color( black ) 

oppure

get-color( ( blue,base ) ) 

Come prima cosa quindi verifichiamo il tipo di dato in ingresso e possiamo farlo utilizzando la funzione di type-of inclusa in SASS:

@function get-color( $name, $map: $colors ) {
	$color: "";

	@if type-of( $name ) == list {
		$color: ...
	} @return $color;
} 

Se il nostro colore è di tipo lista, ovvero specificato con () dobbiamo andare a valorizzare la nostra variabile $color con quello che è il valore associato alla chiave base nella list blue utilizzando un'altra funzione di SASS ovvero map-get.

map-get ritorna il valore di una chiave all'interno di una mappa map-get( $map, $key ), nel nostro caso quindi dovremo scomporre $name utilizzando nth ritornando prima la mappa di valori relativa al primo valore, ovvero blue con:

map-get( $map, nth( $name, 1 ) )

e la chiave da estrarre che sarà:

nth( $name, 2 )

A questo punto questi due valori andremo ad inserirli nel nostro map-get da associare alla variabile $color:

@function get-color( $name, $map: $colors ) {
	$color: "";

	@if type-of( $name ) == list {
		$color: map-get( map-get( $map, nth( $name, 1 ) ), nth( $name, 2 ) );
	} @return $color;
} 

Andiamo ora a completare la nostra funzione con il caso del colore semplice, sempre utilizzando map-get aggiungendo anche una segnalazione di errore nel caso in cui al termine delle varie computazioni la variabile $color sia ancora vuota:

@function get-color( $name, $map: $colors ) {
	$color: "";

	@if type-of( $name ) == list {
		$color: map-get( map-get( $map, nth( $name, 1 ) ), nth( $name, 2 ) );
	} @else {
		$color: map-get( $map, $name );
	} @if $color == '' {
		@error "undefined color";
	} @return $color;
} 

Applicazione

Ci siamo, abbiamo finalmente una mappa di configurazione per i colori e ci siamo creati anche la nostra funzione per estrarli, a questo punto non ci resta che vedere come utilizzarla:

body {
    color: get-color( black );
} a {
    border-bottom: 1px solid get-color( ( blue,base ) );
} 

Probabilmente in alcuni casi di applicazione, come per esempio get-color( black ) questo approccio potrà sembrare eccessivamente verboso, però posso garantirvi che vi porterà a prestare più attenzione all'organizzazione dei colori, inoltre se utilizzate un editor che supporta Snippet potete crearvi la vostra shortcut per risparmiare tempo.

Potete trovare in questo pen tutto il codice spiegato in questo post.

Nel prossimo post vedremo come gestire la parte tipografica.

Blog