Skip to content

In questi giorni nei ritagli di tempo stiamo lavorando ad una landing page per Evolve, che speriamo di riuscire a completare prima del WordCamp Milano 2019 e dal momento in cui ci sono molte animazioni e oggetti in movimento ci siamo chiesti che approccio seguire per rendere accessibile il contenuto.

Gli oggetti in movimento se ci pensate sono increbilimente frequenti nei siti web, dalle più popolari parallax agli effetti di entrata sempre più pacchiani sui vari blocchi in pagina che vanno a comporre delle vere e proprie trappole per chi soffre di epilessia o disfunzioni vestibolari.

I sistemi operativi, come MacOS per esempio, hanno una sezione dedicata all’accessibilità e nello specifico, nella sezione “Monitor”, troviamo una checkbox che ci permette di ridurre il movimento degli elementi sullo schermo.

Il nostro compito come frontend developer è quello di creare dei layout che siano accessibili, e per gestire questo particolare caso ci vengono in aiuto quelle che sono chiamate User preference media queries e ci permettono di interagire con queste preferenze, nello specifico abbiamo la media query prefers-reduced-motion che ha due stati:

  • reduce: per verificare se l’utente ha attivato l’opzione di riduzione movimento
  • no-preference: per verificare se l’utente non ha attivato l’opzione di riduzione movimento.

L’applicazione di questa media query è molto semplice e possiamo scegliere sostanzialmente di applicarla in due modi, disattivando le animazioni se l’opzione è attiva oppure definendo le animazioni solo se l’opzione non è attiva.

/* Disattiviamo la transizione o animazione se l'opzione è attiva. */
@media (prefers-reduced-motion: reduce) {
    .box {
        transition: none;
    }
}

/* Definiamo la transizione o animazione se l'opzione è disattivata. */
@media (prefers-reduced-motion: no-preference) {
    .box {
        transition: transform 1s ease;
    }
}

Dopo aver visto come è possibile organizzare e gestire i colori in un progetto grazie alle mappe di SASS vediamo come gestire la tipografia.

La tipografia è leggermente più complessa rispetto ai colori perché ogni singola dichiarazione è composta da più proprietà e come per i colori il primo passo che ho fatto è stato quello di chiedermi come mi sarebbe piaciuto organizzare il file di configurazione per renderlo comprensibile senza impazzire con mille nomi di variabili.

Con questa organizzazione volevo raggiungere sostanzialmente due obiettivi:

  1. Poter stampare tutte le regole associate ad un tag semplicemente chiamando il suo nome
  2. Stampare una regola specifica di un tag

Ho scelto quindi di organizzare la mia mappa per la tipografia in questo modo:

$fonts: (
     h1: (
         font-size: 48px,
         line-height: 1.1,
         font-weight: 700
     ),
     p: (
         font-size: 16px,
         line-height: 1.5,
         font-weight: 400
     ),
     text_small: (
         font-size: 12px
     )
 );

Primo obiettivo: stampare tutto le regole associate ad una chiave specifica

Per raggiungere il primo obiettivo l’approccio che seguiremo sarà quello di creare un mixin, che chiameremo “font”, che accetti un parametro in ingresso per la chiave e uno per la mappa, che come per i colori imposteremo con un default.

Andiamo quindi a sviluppare il nostro mixin: @mixin font( $type, $map: $font )

A questo punto abbiamo bisogno di ciclare sulle mappe legate ad ogni singola chiave e possiamo farlo utilizzando la funzionalità di @each.

Con il primo ciclo andremo a crearci due variabili che chiameremo $t e $v, rispettivamente con il nome del tag, per esempio h1 e la sua mappa di valori font-size: 48px e così via.

@mixin font( $type, $map: $fonts ) {
     @each $t, $v in $map {
         …
     }
 }

Ora che siamo in grado di elencare tutte le chiavi della nostra mappa dobbiamo come prima cosa verificare che quella che stiamo passando al nostro mixin come $type esista veramente e per farlo possiamo usare map-has-key, in caso contrario ritorniamo un errore:

@mixin font( $type, $map: $fonts ) {
     @each $t, $v in $map {
         @if map-has-key( $map, $type ) {
             …
         }
         @else {
             @error "type non existent";
         }
     }
 }

Siamo arrivati alla conclusione del nostro mixin, non ci resta altro che stampare tutte le regole contenute nella mappa della nostra chiave se corrisponde a quella passata al nostro mixin:

@mixin font( $type, $map: $fonts ) {
     @each $t, $v in $map {
         @if map-has-key( $map, $type ) {
             @if $t == $type {
                 @each $prop, $val in $v {
                     #{$prop}: $val;
                 }
             }
         }
         @else {
             @error "type non existent";
         }
     }
 }

Secondo obiettivo: stampare una regola specifica di un tag

Il precedente mixin ci permetterà di coprire l’80% buono del nostro progetto, tuttavia potremo aver bisogno in alcuni casi di richiamare una proprietà specifica, per farlo ho scelto di crearmi una funzione che mi ritorna solo il valore di una proprietà e un mixin che funge da shortcut, ma del tutto opzionale.

Vediamo prima la funzione, che chiameremo font-get-property, e accetterà tre parametri in ingresso, la chiave, la proprietà che vogliamo estrarre e la mappa di font di riferimento come nel caso precedente.

Questa funzione a livello di struttura è quasi del tutto simile al mixin precedentemente creato:

@function font-get-property( $type, $property, $map: $fonts ) {
     @each $t, $v in $map {
         @if map-has-key( $map, $type ) {
             @if $t == $type {
                 …
             }
         }
         @else {
             @error "type non existent";
         }
     }
 }

All’interno del nostro @if a questo punto andremo a valorizzare una variabile $props con la mappa di valori appartenenti alla nostra chiave:

$props: map-get( $map, $type );

sfruttando map-has-key che abbiamo visto precedentemente verificheremo che esista la proprietà che vogliamo estrarre nella mappa e la ritorniamo:

@if map-has-key( $props, $property ) {
     @return map-get( $props, $property );
 }
 @else {
     @error "prop non existent";
 }

La funzione completa sarà la seguente:

@function font-get-property( $type, $property, $map: $fonts ) {
	@each $t, $v in $map {
		@if map-has-key( $map, $type ) {
			@if $t == $type {
				$props: map-get( $map, $type );

				@if map-has-key( $props, $property ) {
					@return map-get( $props, $property );
				}
				@else {
					@error "prop non existent";
				}
			}
		}
		@else {
			@error "type non existent";
		}
	}
}

e potremo utilizzarla in questo modo:

.main-heading {
     font-size: font-get-property( h1, font-size );
 }

il che ci porta al mixin di cui parlavo prima, visto che come potete notare con questo approccio dobbiamo scrivere il nome della proprietà due volte.

Possiamo a questo punto creare un mixin che chiameremo font-property, parametrizzato esattamente come la funzione che di fatto si occuperà di stampare proprietà e valore in un colpo solo:

@mixin font-property( $type, $property, $map: $fonts ) {
 #{$property}: font-get-property( $type, $property, $map );
}

e lo andremo ad applicare in questo modo:

.main-heading {
	@include font-property( h1, font-size );
}

Non sarà sicuramente il sistema migliore del mondo e c’è ancora qualcosa su cui non sono ancora soddisfatto (ovvero la gestione della parte responsive) ma ritengo sia più strutturato rispetto alle variabili.

Nel prossimo post vedremo come le mappe possono migliorare la gestione delle media queries.

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.

Ho perso il conto di quante volte mi è stato chiesto come fare a scegliere un buon tema, perché essendo autori di temi automaticamente tutti pensano che siamo in grado di scegliere un tema buono piuttosto che uno scritto male.

La verità è che non è per niente semplice anche per chi lavora dietro le quinte, spesso e volentieri ci si trova a scoprire la qualità di un tema solo quando si mette mano al codice.

Voglio provare a fare un piccolo e personale elenco di aspetti da tenere conto quando si sta scegliendo un tema per il nostro progetto.

Non basarsi unicamente sul numero di vendite e recensioni

Il numero di download o di recensioni non necessariamente rendono un tema affidabile o più banalmente adatto al vostro progetto.

Se un tema ha tutte recensioni positive tendiamo automaticamente a considerarlo come di alta qualità, le cose non stanno esattamente così però.

Stessa cosa riguarda il numero di download, bisogna sempre contestualizzarle con data di rilascio e prezzo del prodotto, ma di nuovo, questo non è rilevante per quanto mi riguarda quando si deve scegliere un tema.

Se un tema è andato bene a 10000000 di persone non è automaticamente detto che vada bene anche a me, potrà sembrare un pò duro come concetto ma è come la penso.

A prescindere da quello che sono le recensioni o il numero di download fate una valutazione su quello che sono le recensioni riguardanti il supporto, che in fin dei conti è l’unica cosa che conta veramente, anche se bisogna precisare che i grossi autori hanno quasi sempre il supporto in outsourcing quindi l’esperienza può essere variabile.

Controllare con attenzione che tutte le funzionalità richieste dal nostro progetto siano realizzabili senza ulteriori customizzazioni

Questo è anche l’errore che si commette più spesso, farsi in qualche modo ingannare dalla demo che si vede online senza analizzare con attenzione come sono state realizzate alcune cose che possono essere determinanti nel nostro progetto.

Mi rendo perfettamente conto che questo aspetto è forse il più complesso da analizzare perché sono richieste competenze anche di sviluppo in quanto dovremo essere in grado di ispezionare il codice da browser e valutare come sono stati realizzati i blocchi che ci interesserà utilizzare.

Vi faccio un esempio più pratico, diciamo che ci siamo innamorati dell’effetto al mouse over sui blocchi di testo (text box style 01) di questo tema.

Lo installiamo e iniziamo ad inserire i testi, ma fermi tutti, noi non abbiamo esattamente la stessa frase da due righe per ogni blocco!

Se ispezioniamo il codice possiamo vedere come questo blocco preveda uno shift di 30px dal top, rendendolo funzionante (per funzionante intendo che tutti gli elementi sono perfettamente allineati verticalmente) solo con 2 righe di testo.

A questo punto se vogliamo esattamente quell’effetto saremo costretti a modificarci a mano Javascript e CSS per questo componente perdendo di conseguenza parecchio tempo non preventivato inizialmente.

Analizzare come il tema gestisce font e colori, soprattutto responsive

La gestione dei font e dei colori è cruciale, se gli ultimi possono essere un problema diciamo più facilmente aggirabile il primo invece può banalmente portarci via diverse ore di personalizzazioni e ottimizzazioni.

Se questa informazione non dovesse essere chiara dalla demo o dai dettagli della pagina di presentazione del tema cercate nella documentazione, se pubblica, altrimenti chiedete direttamente all’autore.

È importantissimo che un tema vi metta a disposizione la possibilità di aggiungere una nuova famiglia di font e collegarla agli elementi del tema senza dover scrivere CSS custom e relativo codice per includere il font.

Lato responsive invece si fa più complessa la situazione perché è molto frequente trovare temi che gestiscono questo aspetto in modo approssimativo portandoci quasi sempre a dover fare delle modifiche a mano, specialmente alla tipografia.

Fare attenzione quando si scelgono temi multi purpose

Di temi multi purpose se ne potrebbe parlare per ore, sono in qualche modo croce e delizia dell’ecosistema di WordPress, da un lato ci mettono a disposizione una grande flessibilità ma dall’altro ce la fanno pagare cara in fatto di performance e architettura generale.

I temi multi purpose sono probabilmente i più complessi da valutare perché dalla semplice demo è quasi impossibile capirne l’architettura di opzioni o semplicemente la possibilità di personalizzazione lato template e quelli che sono i difetti di progettazione emergono solo una volta che ci si mettono le mani sopra.

Per quanto mi riguarda possono in qualche modo funzionare solo su progetti con poco budget e se si sceglie di utilizzarli rientrando nei loro standard grafici (ricalcando fedelmente una delle demo proposte), diversamente diventano un investimento di tempo e soldi troppo grosso.

Considerazioni personali

La scelta di un tema non è da sottovalutare, perché può portare a sottostimare incredibilmente il budget per un progetto.

Nell’ultimo anno abbiamo visto aumentare considerevolmente la richiesta di temi custom, il cliente arriva mediamente più preparato del passato su quello che è WordPress e probabilmente inizia a percepire il senso di déjà vu o effetto bootstrap che aleggia nel web sentendo il bisogno di rendere più unica la sua immagine.

Probabilmente non sarà la scelta più popolare, ma ritengo che lo sviluppo di un tema custom sia sempre la soluzione preferibile in determinati progetti per poter garantire uno standard più alto e soprattutto avere il pieno controllo sull’ottimizzazione.