Articolo originale: https://www.freecodecamp.org/news/the-css-handbook-a-handy-guide-to-css-for-developers-b56695917d11/

Ho scritto questo manuale per aiutarti a imparare velocemente il CSS e acquisire familiarità con concetti avanzati.

Il CSS è spesso liquidato dagli sviluppatori come una cosa facile da imparare, o considerato come qualcosa da usare soltanto quando si ha bisogno di impostare rapidamente lo stile di una pagina o di una app. Per questa ragione, viene spesso imparato sul momento, oppure si tende a imparare concetti isolati quando occorre utilizzarli. Ciò può essere un'enorme fonte di frustrazione quando scopriamo che uno strumento non funziona nel modo desiderato.

Questo manuale ti aiuterà a imparare rapidamente il CSS e ad avere una panoramica delle principali funzionalità moderne che puoi usare per impostare lo stile di pagine web e app.

Spero di aiutarti a ottenere dimestichezza con il CSS e a diventare subito operativo utilizzando questo meraviglioso strumento che ti permette di creare splendidi design sul web.

Clicca qui per scaricare questo manuale in versione PDF / ePub / Mobi (versione originale inglese)

CSS è l'acronimo di Cascading Style Sheets, ed è una delle principali unità costituenti del web. La sua storia risale agli anni '90 e, insieme all'HTML, è cambiato molto sin dalle sue umili origini.

Dato che creo siti web da prima che il CSS esistesse, ho assistito alla sua evoluzione.

Il CSS è uno strumento straordinario e negli ultimi anni è cresciuto molto, introducendo molte funzionalità incredibili come CSS Grid, Flexbox e le proprietà  CSS personalizzate.

Questo manuale è dedicato a un pubblico vasto.

Prima, ai principianti. Spiegherò il CSS da zero in un modo succinto ma completo, in modo da poter usare questo manuale per imparare il CSS dalle basi.

Poi, ai professionisti. Il CSS è spesso considerato come una cosa secondaria da imparare, specialmente dagli sviluppatori JavaScript. Sanno che il CSS non è un vero linguaggio di programmazione, sono programmatori e quindi non dovrebbero preoccuparsi di imparare il CSS nel modo giusto. Ho scritto questo manuale anche per voi.

Infine, a chi conosce il CSS da pochi anni ma non ha avuto l'opportunità di imparare cose nuove. Parleremo a lungo delle nuove funzionalità del CSS, quelle con cui si costruirà il web nella prossima decade.

Il CSS è migliorato molto negli ultimi anni e si sta evolvendo velocemente.

Anche se non scrivi CSS per lavoro, conoscere come funziona ti può risparmiare dei mal di testa quando hai bisogno di capirlo di tanto in tanto, ad esempio ritoccando una pagina web.

Grazie per leggere questo manuale. Il mio obiettivo è di darti una panoramica veloce ma completa del CSS.

Flavio

Puoi contattarmi via mail a flavio@flaviocopes.com, o su Twitter @flaviocopes.

Il mio sito web è flaviocopes.com.

Sommario

INTRODUZIONE AL CSS

Il CSS (acronimo di Cascading Style Sheets) è il linguaggio che utilizziamo per definire lo stile di un file HTML e comunicare al browser come dovrebbe presentare gli elementi sulla pagina.

In questo manuale parlerò esclusivamente dello stile dei documenti HTML, anche se il CSS può essere usato anche per altro.

Un file CSS contiene svariate regole CSS.

Ogni regola è composta da due parti:

  • il selettore
  • il blocco di dichiarazione

Il selettore è una stringa che identifica uno o più elementi della pagina, secondo una sintassi speciale di cui parleremo accuratamente.

Il blocco di dichiarazione contiene una o più dichiarazioni, ognuna composta da coppie di proprietà e valori.

Questo è tutto ciò che abbiamo nel CSS.

Organizzare attentamente le proprietà, associar loro valori e applicarli a specifici elementi sulla pagina usando un selettore, corrisponde all'intero programma di questo manuale.

Che aspetto ha il CSS

Un insieme di regole CSS ha una parte chiamata selettore e un'altra parte chiamata dichiarazione. La dichiarazione contiene varie regole, ognuna composta da una proprietà e da un valore.

In questo esempio, p è il selettore e applica una regola che imposta il valore 20px alla proprietà font-size:

p {
  font-size: 20px;
}

Più regole possono susseguirsi una dopo l'altra:

p {
  font-size: 20px;
}

a {
  color: blue;
}

Un selettore può seleziona uno o più elementi:

p, a {
  font-size: 20px;
}

E può selezionare tag HTML, come qui sopra, o elementi HTML che contengono un certo attributo class con .nome-classe, o elementi HTML che hanno uno specifico attributo id con #nome-id.

Selettori più avanzati consentono di scegliere elementi i cui attributi corrispondono a un valore specifico, o anche elementi che corrispondono a pseudo-classi (ne riparleremo in seguito).

Punti e virgola

Ogni regola CSS termina con un punto e virgola. I punti e virgola non sono opzionali, eccetto per l'ultima regola. Ma suggerisco di usali sempre per uniformità e per evitare errori se aggiungi un'altra proprietà e dimentichi aggiungere il punto e virgola nella riga precedente.

Formattazione e indentazione

Non esiste una regole fissa per la formattazione. Questo è CSS valido:

p
      {
  font-size:           20px   ;
                      }
                      
a{color:blue;}

Ma basta vederlo per provare dolore. Adotta una convenzione, come quella che hai visto negli esempi precedenti: scrivi i selettori e le parentesi sulla sinistra, indenta di due spazi ogni regola, metti la parentesi d'apertura sulla stessa riga del selettore, separati da uno spazio.

Un uso corretto e uniforme della spaziatura e dell'indentazione è un aiuto visuale per comprendere il tuo codice.

BREVE STORIA DEL CSS

Prima di proseguire, voglio darti un piccolo riepilogo della storia del CSS.

Il CSS è nato dalla necessità di definire lo stile delle pagine web. Prima che il CSS fosse adottato, le persone volevano un modo per determinare lo stile delle pagine web, che a quei tempi avevano tutte un aspetto molto simile e "accademico". Non si poteva fare molto in termini di personalizzazione.

L'HTML 3.2 ha introdotto l'opzione di definire i colori inline, come attributi degli elementi HTML, e i tag di presentazione come center e font, ma il tutto è diventato velocemente una situazione ben lontana da quella ideale.

Il CSS ci fa spostare tutto ciò che è legato alla presentazione dall'HTML al CSS, in modo che l'HTML possa ritornare al formato che definisce la struttura del documento, piuttosto che definire l'aspetto che dovrebbe avere nel browser.

Il CSS è in costante evoluzione e il CSS che hai utilizzato 5 anni fa potrebbe essere obsoleto, con le nuove tecniche CSS idiomatiche e i cambiamenti dei browser.

È difficile immaginare quanto fosse diverso il web ai tempi in cui è nato il CSS.

In quel momento, c'erano svariati browser in competizione, i principali erano Internet Explorer o Netscape Navigator.

Lo stile delle pagine veniva definito usando l'HTML, con speciali tag di presentazione come bold e attributi speciali, la maggior parte dei quali ora è obsoleta.

Ciò voleva dire avere opportunità di personalizzazione limitate.

Il grosso delle decisioni riguardanti lo stile veniva lasciato al browser.

Inoltre, si costruiva un sito specificamente per un browser, perché ognuno usava dei tag non standard per avere più potere e possibilità.

Presto le persone si sono rese conto della necessità di un modo per definire lo stile delle pagine, un modo che funzionasse in tutti i browser.

Dopo l'idea iniziale proposta nel 1994, il primo rilascio del CSS risale al 1996, quando le linee guida per il CSS di livello 1 ("CSS 1") furono pubblicate.

Il CSS di livello 2 (“CSS 2”) fu pubblicato nel 1998.

Da allora, iniziò il lavoro sul CSS di livello 3. Il gruppo di lavoro del CSS decise di dividere ogni funzionalità e lavorarvi separatamente, in moduli.

I browser non erano molto rapidi a implementare il CSS. Abbiamo dovuto attendere fino al 2002 per avere il primo browser in grado di implementare tutte le caratteristiche del CSS, ovvero IE per Mac.

Internet Explorer implementava il modello a scatola (box model) in modo errato fin dall'inizio, portando ad anni dolorosi verso la ricerca di uno stile applicato in modo uniforme sui browser. Avevamo diversi stratagemmi e trucchetti per fare i modo che i browser presentassero le cose nel modo desiderato.

Oggi va molto molto meglio. Possiamo usare semplicemente il CSS standard senza pensare a cose strane, per la maggior parte del tempo, e il CSS non è mai stato così potente.

Ora non abbiamo più numeri di rilascio ufficiali per il CSS, ma il gruppo di lavoro del CSS rilascia uno "snapshot" (ovvero un'istantanea) dei moduli attualmente considerati stabili e pronti per essere inclusi nei browser. Questo è l'ultimo snapshot, del 2018: https://www.w3.org/TR/css-2018/

N.d.T.
L'ultimo snapshot rilasciato al momento della traduzione è: https://www.w3.org/TR/css-2021/

Il CSS di livello 2 è ancora la base per il CSS che scriviamo oggi, e abbiamo molte altre funzionalità costruite su di esso.

AGGIUNGERE IL CSS A UNA PAGINA HTML

Il CSS viene incluso in una pagina HTML in diversi modi.

Il tag link è il modo per includere un file CSS. È il modo preferibile per usare il CSS, così come ne è stato progettato l'utilizzo: un file CSS viene incluso in tutte le pagine di un sito e cambiare una riga di questo file influisce sulla presentazione di tutte le pagine del sito.

Per usare questo metodo, devi aggiungere un tag link con un attributo href che punta al file CSS che vuoi includere. Va aggiunto all'interno del tag head del sito (non all'interno del tag body):

<link rel="stylesheet" type="text/css" href="myfile.css">

Sono richiesti anche gli attributi rel e type, in quanto dicono al browser che tipo di file stai linkando.

2: usare il tag style

Invece di usare il tag link per selezionare un foglio di stile separato contenente il CSS, possiamo aggiungere il CSS direttamente in un tag style. La sintassi è:

<style>
...il nostro CSS...
</style>

Usare questo metodo evita di creare un file CSS separato. Trovo che questo sia un buon modo per sperimentare prima di "formalizzare" il CSS in un  file separato o per aggiungere una riga speciale di CSS a un file.

3: stili inline

Gli stili inline sono il terzo modo per aggiungere del CSS a una pagina. Possiamo aggiungere un attributo style a ogni tag HTML e aggiungere il CSS all'interno.

<div style="">...</div>

Esempio:

<div style="background-color: yellow">...</div>

SELETTORI

Un selettore ci consente di associare una o più dichiarazioni a uno o più elementi sulla pagina.

Selettori base

Supponiamo di avere un elemento p sulla pagina e che vogliamo mostrare le parole al suo interno usando il colore giallo.

Possiamo selezionare questo elemento usando un selettore p, che seleziona tutti gli elementi che hanno il tag p nella pagina. Una semplice regola CSS per ottenere ciò che vogliamo è:

p {
  color: yellow;
}

Ogni elemento HTML ha un selettore corrispondente, per esempio: div, span, img.

Se un selettore corrisponde a più elementi, tutti questi elementi nella pagina saranno interessati dal cambiamento.

Gli elementi HTML hanno 2 attributi che sono usati molto frequentemente nel CSS per associare uno stile a uno specifico elemento sulla pagina: class e id.

C'è una grande differenza tra questi due: all'interno di un documento HTML puoi ripetere lo stesso valore di attributo class su più elementi, ma puoi usare un id soltanto una volta. A corollario, usando le classi puoi selezionare un elemento con 2 o più attributi class specifici, cosa che non è possibile con gli id.

Le classi sono identificate dal simbolo ., mentre gli id dal simbolo #.

Esempio usando una classe:

<p class="dog-name">
  Roger
</p>

.dog-name {
  color: yellow;
}

Esempio usando un id:

<p id="dog-name">
  Roger
</p>

#dog-name {
  color: yellow;
}

Combinare i selettori

Finora, abbiamo visto come selezionare un elemento, una classe o un id. Adesso, introduciamo dei selettori più potenti.

Selezionare un elemento con una classe o un id

Puoi selezionare uno specifico elemento che possiede un attributo class o id.

Esempio usando una classe:

<p class="dog-name">
  Roger
</p>

p.dog-name {
  color: yellow;
}

Esempio usando un id:

<p id="dog-name">
  Roger
</p>

p#dog-name {
  color: yellow;
}

Perché dovresti farlo se la classe o l'id forniscono già un modo per selezionare l'elemento? Per avere più specificità. Vedremo più avanti cosa vuol dire.

Selezionare classi multiple

Puoi selezionare un elemento con una classe specifica usando .nome-classe, come abbiamo visto precedentemente. Puoi selezionare un elemento con 2 (o più) classi combinando i nomi delle classi separati da un punto, senza spazi.

Esempio:

<p class="dog-name roger">
  Roger
</p>

.dog-name.roger {
  color: yellow;
}

Combinare classi e id

Nello stesso modo puoi combinare una classe e un id.

Esempio:

<p class="dog-name" id="roger">
  Roger
</p>

.dog-name#roger {
  color: yellow;
}

Raggruppare i selettori

Puoi combinare dei selettori per applicare le stesse dichiarazioni a selettori multipli. Per farlo, devi separarli con una virgola.

Esempio:

<p>
  My dog name is:
</p>
<span class="dog-name">
  Roger
</span>

p, .dog-name {
  color: yellow;
}

Per rendere le cose più chiare, in queste dichiarazioni puoi aggiungere degli spazi:

p,
.dog-name {
  color: yellow;
}

Seguire l'albero del documento con i selettori

Abbiamo visto come selezionare un elemento nella pagina usando il nome di un tag, di una classe o di un id.

Puoi creare un selettore più specifico combinando più elementi per seguire la struttura ad albero del documento. Ad esempio, se hai un tag span annidato all'interno di un tag p, puoi selezionarlo senza applicare lo stile a un tag span non incluso in un tag p:

<span>
  Hello!
</span>
<p>
  My dog name is:
  <span class="dog-name">
    Roger
  </span>
</p>

p span {
  color: yellow;
}

Osserva come abbiamo usato una spazio tra p e span.

Ciò funziona anche se l'elemento sulla destra si trova in profondità di vari livelli.

Per rendere restringere la dipendenza al primo livello, puoi usare il simbolo > tra i due elementi:

p > span {
  color: yellow;
}

In questo caso, se uno span non è il primo figlio di un elemento p, non gli verrà applicato il colore giallo .

Ai figli diretti verrà applicato lo stile:

<p>
  <span>
    Questo è giallo
  </span>
  <strong>
    <span>
      Questo non è giallo
    </span>
  </strong>
</p>

I selettori di fratelli adiacenti ci consentono di definire lo stile di un elemento solo se preceduto da un elemento specifico. Possiamo farlo usando l'operatore +.

Esempio:

p + span {
  color: yellow;
}

In questo modo, il colore giallo sarà assegnato a tutti gli elementi span preceduti da un elemento p:

<p>Questo è un paragrafo</p>
<span>Questo è uno span giallo</span>

Esistono tanti altri selettori da poter usare:

  • selettori di attributi
  • selettori di pseudo-classi
  • selettori di pseudo-elementi

Parleremo di loro nelle prossime sezioni.

CASCADE

Cascade (letteralmente "cascata"), è un concetto fondamentale del CSS. Dopo tutto, è il suo nome, la prima C di CSS – Cascading Style Sheets – deve essere una cosa importante.

Cosa vuol dire?

Cascade è il processo, o algoritmo, che determina le proprietà applicate a ogni elemento sulla pagina, provando a convergere da una lista di regole CSS definite in varie posizioni.

Fa tutto ciò prendendo in considerazione:

  • specificità
  • importanza
  • ereditarietà
  • ordine nel file

Si occupa anche di risolvere i conflitti.

Due o più regole CSS in competizione per la stessa proprietà applicata allo stesso elemento devono essere elaborate secondo le specifiche CSS, per determinare quale deve essere applicata.

Anche se hai solo un file CSS caricato dalla tua pagina, c'è altro CSS che fa parte del processo, come il CSS del browser (user agent). I browser possiedono un insieme di regole predefinite, tutte diverse tra i browser.

Poi entra in gioco il tuo CSS.

E il browser applica il foglio di stile dell'utente, che potrebbe essere anche applicato da estensioni del browser.

Tutte queste regole concorrono alla presentazione della pagina.

Adesso ci occuperemo dei concetti di specificità e ereditarietà.

SPECIFICITÀ

Cosa accade se un elemento viene selezionato da più regole, con diversi selettori che influiscono sulla stessa proprietà?

Ad esempio, prendiamo in considerazione questo elemento:

<p class="dog-name">
  Roger
</p>

Possiamo avere

.dog-name {
  color: yellow;
}

e un'altra regola che seleziona p, che imposta il colore su un altro valore

p {
  color: red;
}

e un'altra regola che seleziona p.dog-name. Quale regola avrà la precedenza sulle altre e perché?

Vince la regola più specifica. Se due o più regole hanno la stessa specificità, quella che appare per ultima vince.

A volte, ciò che è in pratica più specifico crea un po' di confusione nei principianti. Direi che confonde anche gli esperti che non hanno a che fare frequentemente con queste regole, o semplicemente le sottovalutano.

Come calcolare la specificità

La specificità è calcolata usando una convenzione.

Abbiamo 4 slot, ognuno parte da 0: 0 0 0 0. Lo slot a sinistra è il più importante e quello a destra il meno importante.

Come per i numeri nel sistema decimale: 1 0 0 0 è maggiore di 0 1 0 0.

Slot 1

Il primo slot, quello più a destra, è il meno importante.

Aumentiamo questo valore quando abbiamo un selettore di elemento. Un elemento è il nome di un tag. Se c'è più di un selettore di elemento nella regola, di conseguenza si aumenta il valore dello slot.

Esempi:

p {}                    /* 0 0 0 1 */
span {}                 /* 0 0 0 1 */
p span {}               /* 0 0 0 2 */
p > span {}             /* 0 0 0 2 */
div p > span {}         /* 0 0 0 3 */

Slot 2

Il secondo slot è incrementato da 3 cose:

  • selettori di classe
  • selettori di pseudo-classe
  • selettori di attributi

Ogni volta che una regola contiene uno di questi selettori, incrementiamo il valore della seconda colonna da destra.

Esempi:

.name {}                 /* 0 0 1 0 */
.users .name {}          /* 0 0 2 0 */
[href$='.pdf'] {}        /* 0 0 1 0 */
:hover {}                /* 0 0 1 0 */

Naturalmente, i selettori dello slot 2 possono essere combinati con quelli dello slot 1:

div .name {}             /* 0 0 1 1 */
a[href$='.pdf'] {}       /* 0 0 1 1 */
.pictures img:hover {}   /* 0 0 2 1 */

Un trucco utile con le classi è ripetere la stessa classe per aumentare la specificità. Ad esempio:

.name {}              /* 0 0 1 0 */
.name.name {}         /* 0 0 2 0 */
.name.name.name {}    /* 0 0 3 0 */

Slot 3

Lo slot 3 contiene le cose più importanti che possono influire sulla specificità in un file CSS: gli id.

A ogni elemento può essere assegnato un attributo id e possiamo usarlo nel nostro foglio di stile per selezionare un elemento.

Esempi:

#name {}                    /* 0 1 0 0 */
.user #name {}              /* 0 1 1 0 */
#name span {}               /* 0 1 0 1 */

Slot 4

Lo slot 4 risente degli stili inline. Qualsiasi stile inline avrà precedenza su ogni regola definita in un file CSS esterno o all'interno del tag style nell'intestazione della pagina.

Esempi:

<p style="color: red">Test</p> /* 1 0 0 0 */

Anche se un'altra regola CSS definisce il colore, questo stile inline sarà applicato. Eccetto per un caso – se viene usato !important, il che riempie lo slot 5.

Importanza

La specificità non conta se una regola termina con !important:

p {
  font-size: 20px!important;
}

Questa regola avrà la precedenza su ogni altra regola con più specificità.

Aggiungere !important in una regola CSS, la renderà più importante di qualsiasi altra regola, in accordo con le regole di specificità. L'unico altro modo in cui una regola può acquisire precedenza è avere anch'essa !important e avere specificità maggiore negli altri slot meno importanti.

Suggerimenti

In generale, dovresti usare la specificità necessaria, ma non di più. In questo modo, puoi creare altri selettori per sovrascrivere le regole definite in precedenza senza diventare matto.

!important è uno strumento altamente discusso che ci offre il CSS. Molti esperti di CSS sono contrari al suo utilizzo. Mi trovo a utilizzarlo soprattutto quando ho davanti una regola CSS che ha una specificità così alta che ho bisogno di usare !important per applicare nel browser il mio nuovo CSS.

Ma in generale, !important non dovrebbe trovare posto nei tuoi file CSS.

Anche l'uso dell'attributo id per il CSS è altamente discusso, dato che possiede una specificità molto elevata. Una buona alternativa è usare le classi, che hanno meno specificità, sono facili da utilizzare e sono molto efficaci (puoi avere più classi per un elemento e una classe può essere riutilizzata più volte).

Strumenti per calcolare la specificità

Puoi usare il sito https://specificity.keegan.st/ per eseguire automaticamente calcoli di specificità.

È utile soprattutto se stai cercando di capire delle cose, visto che può essere uno strumento per avere un riscontro.

EREDITARIETÀ

Quando imposti alcune proprietà su un selettore CSS, queste vengono ereditate da tutti i figli del selettore.

Ho detto alcune proprietà, perché non tutte mostrano questo comportamento.

Ciò accade perché ha senso che delle proprietà vengano ereditate. Questo aiuta a scrivere del CSS più conciso, dato che non dobbiamo definire esplicitamente di nuovo una proprietà per ogni singolo discendente.

Altre proprietà invece, non ha senso che vengano ereditate.

Pensa al tipo di carattere: non c'è bisogno di applicare font-family a ogni singolo tag di una pagina. Imposti il font nel tag body e ogni discendente lo eredita insieme ad altre proprietà.

La proprietà background-color (il colore di sfondo), d'altro canto, non ha molto senso che venga ereditata.

Proprietà che vengono ereditate

Ecco una lista delle proprietà che vengono ereditate. La lista non è esaustiva, ma queste proprietà sono alcune delle più comuni che ti troverai a usare:

  • border-collapse
  • border-spacing
  • caption-side
  • color
  • cursor
  • direction
  • empty-cells
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font-size-adjust
  • font-stretch
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • orphans
  • quotes
  • tab-size
  • text-align
  • text-align-last
  • text-decoration-color
  • text-indent
  • text-justify
  • text-shadow
  • text-transform
  • visibility
  • white-space
  • widows
  • word-break
  • word-spacing

Le ho riportate da questo bell'articolo su Sitepoint sull'ereditarietà in CSS (risorsa in lingua originale inglese).

Forzare delle proprietà a essere ereditate

E se hai una proprietà che non viene ereditata di default e vuoi che sia ereditata da un figlio?

Nel figlio, devi impostare il valore della proprietà sulla parola chiave speciale inherit.

Esempio:

body {
    background-color: yellow;
}

p {
  background-color: inherit;
}

Forzare delle proprietà a NON essere ereditate

Viceversa, potresti avere una proprietà che viene ereditata e volere che non lo sia.

Puoi usare la parola chiave revert per farlo. In questo caso, viene ripristinato il valore dato dal browser nel suo foglio di stile predefinito.

In pratica, viene usata di rado e il più delle volte ti troverai a impostare semplicemente un altro valore per la proprietà, per sovrascrivere il valore ereditato.

Altri valori speciali

In aggiunta alle parole chiave speciali inherit e revert che abbiamo appena visto, puoi impostare una proprietà su:

  • initial: usa il foglio di stile predefinito del browser, se disponibile. Altrimenti, se la proprietà viene ereditata di default, eredita il valore. In caso contrario, non fa nulla.
  • unset: se la proprietà viene ereditata di default, lo fa. Altrimenti non fa nulla.

IMPORT

Da qualsiasi file CSS puoi importare un altro file usando la direttiva @import.

Ecco come usarla:

@import url(myfile.css)

url() può gestire URL assoluti o relativi.

Una cosa importante che hai bisogno di sapere è che le direttive @import devono essere posizionate prima dell'altro CSS nel file oppure saranno ignorate.

Puoi usare i descrittori dei dispositivi solo per caricare un file CSS su uno specifico dispositivo:

@import url(myfile.css) all;
@import url(myfile-screen.css) screen;
@import url(myfile-print.css) print;

SELETTORI DI ATTRIBUTO

Abbiamo già introdotto diversi selettori CSS di base: usando elementi, classi, id, abbiamo visto come combinarli, come selezionare più classi, come definire lo stile per più selettori nella stessa regola, come seguire la gerarchia della pagina con selettori per i discendenti e i discendenti diretti e per fratelli adiacenti.

In questa sezione, analizzeremo i selettori di attributi e parleremo di selettori di pseudo-classi e pseudo-elementi nelle prossime 2 sezioni.

Selettori per la presenza di un attributo

Il primo tipo di selettore è quello che seleziona un attributo in base alla sua presenza.

Possiamo verificare se un elemento ha un attributo usando la sintassi []. p[id] selezionerà tutti i tag p nella pagina che hanno un attributo id, indipendentemente dal suo valore:

p[id] {
  /* ... */
}

Selettori per il valore esatto di un attributo

All'interno delle parentesi puoi controllare il valore dell'attributo usando il simbolo =, e il CSS sarà applicato solo se l'attributo corrisponde all'esatto valore specificato:

p[id="my-id"] {
  /* ... */
}

Corrispondenza della parte del valore di un attributo

Mentre = ci consente di controllare un valore esatto, abbiamo anche altri operatori:

  • *= verifica se un attributo contiene la parte
  • ^= verifica se un attributo inizia con la parte
  • $= verifica se un attributo finisce con la parte
  • |= verifica se un attributo inizia con la parte ed è seguito da un trattino (comune per le classi, ad esempio), o contiene la parte
  • ~= verifica se la parte è contenuta nell'attributo, ma separata da spazi dal resto

Tutte le verifiche che abbiamo menzionato sono case sensitive (maiuscole e minuscole sono importanti).

Se aggiungi una i prima di chiudere le parentesi, il controllo sarà case insensitive. È supportato da molti browser ma non da tutti, controlla su https://caniuse.com/#feat=css-case-insensitive.

PSEUDO-CLASSI

Le pseudo-classi sono parole chiave predefinite che sono usate per selezionare un elemento in base al suo stato, o per selezionare uno specifico elemento figlio.

Iniziano con i due punti :.

Possono essere usati come parte di un selettore e sono molto utili per definire lo stile di link attivi o visitati, ad esempio, cambiare lo stile su hover, focus, o selezionare il primo figlio, o righe dispari. Davvero utile in molti casi.

Queste sono le pseudo-classi più comuni che ti troverai a utilizzare:

Pseudo-classe Selezione
:active Un elemento attivato (ad esempio, cliccato) dall'utente, principalmente usato per link e pulsanti.
:checked Input di tipo casella di spunta, opzione o radio che sono abilitati.
:default La scelta predefinita di un insieme (come l'opzione di pulsanti radio o menu di scelta).
:disabled Un elemento disabilitato.
:empty Un elemento senza figli.
:enabled Un elemento abilitato (opposto a :disabled).
:first-child Il primo figlio di un gruppo di fratelli.
:focus L'elemento selezionato.
:hover L'elemento su cui si trova il mouse.
:last-child L'ultimo figlio di un gruppo di fratelli.
:link Un link che non è stato visitato.
:not() Ogni elemento che non corrisponde al selettore (ad esempio :not(span)).
:nth-child() Un elemento che corrisponde alla posizione specificata.
:nth-last-child() Un elemento che corrisponde alla posizione specificata, partendo dalla fine.
:only-child Un elemento senza fratelli.
:required Un elemento di un modulo con l'attributo required.
:root Rappresenta l'elemento html. È come selezionare l'elemento html ma è più specifico. Utile per le variabili CSS.
:target L'elemento che corrisponde a un frammento di URL (per navigazione interna alla pagina).
:valid Elemento di un modulo validato con successo dal lato client.
:visited Un link che è stato visitato.

Facciamo un esempio, uno davvero comune. Se desideri definire lo stile di un link, crei una regola CSS per selezionare l'elemento a:

a {
  color: yellow;
}

Sembra andare tutto bene, finché clicchi sul link. Il link torna al colore predefinito (blu) quando viene cliccato. Quando apri un link e poi torni indietro sulla pagina, puoi vedere che il link è blu.

Perché accade?

Perché una volta cliccato, il link cambia stato e passa allo stato :active. E quando è stato visitato si trova nello stato :visited. Per sempre, finché l'utente cancella la cronologia del browser.

Quindi, per far apparire correttamente un link giallo in tutti i suoi stati, devi scrivere:

a,
a:visited,
a:active {
  color: yellow;
}

:nth-child() merita una menzione speciale. Può essere usato per selezionare discendenti dispari o pari con :nth-child(odd) e :nth-child(even).

È comunemente usato nelle liste per colorare le righe dispari in modo diverso dalle righe pari:

ul:nth-child(odd) {
  color: white;
  background-color: black;
}

Puoi usarlo anche per selezionare i primi 3 discendenti di un elemento con :nth-child(-n+3). O puoi anche usarlo per selezionare 1 elemento ogni 5 con :nth-child(5n).

Alcune pseudo-classi sono usate solo per la stampa, come :first, :left, :right, in modo da poter selezionare la prima pagina, tutte le pagine a sinistra e tutte le pagine a destra, che hanno generalmente degli stili leggermente diversi.

PSEUDO-ELEMENTI

Gli pseudo-elementi sono usati per definire lo stile di una parte specifica di un elemento.

Iniziano con i due punti doppi ::.

A volte potrai avvistarli in natura con dei due punti singoli, ma questa è una sintassi supportata solo per ragioni di retrocompatibilità. Dovresti usare i due punti doppi per distinguerli dalle pseudo-classi.

::before e  ::after sono probabilmente gli pseudo-elementi più utilizzati. Vengono usati per aggiungere contenuto prima e dopo un elemento, come delle icone ad esempio.

Ecco la lista degli pseudo-elementi:

Pseudo-elemento Selezione
::after Crea uno pseudo-elemento dopo l'elemento.
::before Crea uno pseudo-elemento prime dell'elemento.
::first-letter Può essere usato per definire lo stile della prima lettera di un blocco di testo.
::first-line Può essere usato per definire lo stile della prima riga di un blocco di testo.
::selection Seleziona il testo selezionato dall'utente.

Facciamo un esempio. Diciamo che vogliamo far sì che la prima riga di un paragrafo abbia una dimensione del carattere leggermente più grande, una cosa comune in tipografia:

p::first-line {
  font-size: 2rem;
}

O magari che la prima lettera sia più marcata:

p::first-letter {
  font-weight: bolder;
}

::after e ::before sono un po' meno intuitivi. Ricordo di averli usati per aggiungere delle icone con il CSS.

Devi specificare la proprietà content per inserire qualsiasi tipo di contenuto dopo o prima di un elemento:

p::before {
  content: url(/myimage.png);
}

.myElement::before {
    content: "Hey Hey!";
}

COLORI

Di default, una pagina HTML viene presentata dai browser in modo piuttosto triste, in termini di colori usati.

C'è uno sfondo bianco, del nero e i link blu. Ecco tutto.

Fortunatamente il CSS ci dà la possibilità di aggiungere colori ai nostri design.

Abbiamo a disposizione queste proprietà:

  • color
  • background-color
  • border-color

Tutte accettano un valore di colore, che può essere espresso in diversi modi.

Nomi di colori

Per iniziare, abbiamo le parole chiave CSS che definiscono i colori. Il CSS ha iniziato con 16, ma oggi c'è un numero enorme di nomi di colori:

  • aliceblue
  • antiquewhite
  • aqua
  • aquamarine
  • azure
  • beige
  • bisque
  • black
  • blanchedalmond
  • blue
  • blueviolet
  • brown
  • burlywood
  • cadetblue
  • chartreuse
  • chocolate
  • coral
  • cornflowerblue
  • cornsilk
  • crimson
  • cyan
  • darkblue
  • darkcyan
  • darkgoldenrod
  • darkgray
  • darkgreen
  • darkgrey
  • darkkhaki
  • darkmagenta
  • darkolivegreen
  • darkorange
  • darkorchid
  • darkred
  • darksalmon
  • darkseagreen
  • darkslateblue
  • darkslategray
  • darkslategrey
  • darkturquoise
  • darkviolet
  • deeppink
  • deepskyblue
  • dimgray
  • dimgrey
  • dodgerblue
  • firebrick
  • floralwhite
  • forestgreen
  • fuchsia
  • gainsboro
  • ghostwhite
  • gold
  • goldenrod
  • gray
  • green
  • greenyellow
  • grey
  • honeydew
  • hotpink
  • indianred
  • indigo
  • ivory
  • khaki
  • lavender
  • lavenderblush
  • lawngreen
  • lemonchiffon
  • lightblue
  • lightcoral
  • lightcyan
  • lightgoldenrodyellow
  • lightgray
  • lightgreen
  • lightgrey
  • lightpink
  • lightsalmon
  • lightseagreen
  • lightskyblue
  • lightslategray
  • lightslategrey
  • lightsteelblue
  • lightyellow
  • lime
  • limegreen
  • linen
  • magenta
  • maroon
  • mediumaquamarine
  • mediumblue
  • mediumorchid
  • mediumpurple
  • mediumseagreen
  • mediumslateblue
  • mediumspringgreen
  • mediumturquoise
  • mediumvioletred
  • midnightblue
  • mintcream
  • mistyrose
  • moccasin
  • navajowhite
  • navy
  • oldlace
  • olive
  • olivedrab
  • orange
  • orangered
  • orchid
  • palegoldenrod
  • palegreen
  • paleturquoise
  • palevioletred
  • papayawhip
  • peachpuff
  • peru
  • pink
  • plum
  • powderblue
  • purple
  • rebeccapurple
  • red
  • rosybrown
  • royalblue
  • saddlebrown
  • salmon
  • sandybrown
  • seagreen
  • seashell
  • sienna
  • silver
  • skyblue
  • slateblue
  • slategray
  • slategrey
  • snow
  • springgreen
  • steelblue
  • tan
  • teal
  • thistle
  • tomato
  • turquoise
  • violet
  • wheat
  • white
  • whitesmoke
  • yellow
  • yellowgreen

più tranparent e currentColor che puntano alla proprietà color. Ad esempio, è utile fare in modo che border-color li erediti.

Sono definiti nel Modulo CSS Colori, livello 4, e sono case insensitive.

Wikipedia ha una simpatica tabella che ti permette di scegliere un colore con il suo nome.

I nomi dei colori non solo la sola opzione.

RGB e RGBa

Puoi usare la funzione rgb() per calcolare un colore dalla notazione RGB (red-green-blue), che imposta il colore in base alle sue parti di rosso-verde-blu. Da 0 a 255:

p {
  color: rgb(255, 255, 255); /* white */
    background-color: rgb(0, 0, 0); /* black */
}

rgba() ti consente di aggiungere il canale alfa per inserire la trasparenza. Può essere un numero tra 0 e 1:

p {
    background-color: rgb(0, 0, 0, 0.5);
}

Notazione esadecimale

Un'altra opzione è esprimere le parti RGB dei colori in notazione esadecimale, che è composta da tre blocchi.

Il nero, che è rgb(0,0,0), è espresso come #000000 o #000 (possiamo accorciare i 2 numeri in 1 se sono uguali).

Il bianco, rgb(255,255,255), è espresso come #ffffff o #fff.

La notazione esadecimale ci permette di esprimere un numero da 0 a 255 in sole due cifre, dato che vanno da 0 a "15" (f).

Possiamo aggiungere il canale alfa aggiungendo 1 o 2 cifre alla fine, ad esempio, #00000033. Non tutti i browser supportano la notazione accorciata, quindi utilizza tutte e 6 le cifre per esprimere le parti RGB.

HSL e HSLa

Questa è un'aggiunta più recente al CSS.

HSL = Hue Saturation Lightness (ovvero tonalità, saturazione e luminosità).

In questa notazione, il nero è hsl(0, 0%, 0%) e il bianco è hsl(0, 0%, 100%).

Se hai più familiarità con HSL rispetto a RGB per le tue conoscenza pregresse, puoi farne sicuramente uso.

Abbiamo anche hsla(), che aggiunge il canale alfa al mix. Ancora, un numero tra 0 e 1: hsl(0, 0%, 0%, 0.5)

UNITÀ

Una delle cose che utilizzerai quotidianamente nel CSS sono le unità. Sono usate per definire lunghezze, padding, margini, allineare elementi e via dicendo.

Cose come px, em, rem o percentuali.

Sono ovunque. Ne esistono anche di misteriose. Affronteremo ognuna di esse in questa sezione.

Pixel

L'unità di misura maggiormente usata. Un pixel non corrisponde effettivamente a un pixel fisico sullo schermo, in quanto varia, e parecchio, a seconda del dispositivo (pensa ai dispositivi con alto numeri di DPI contro i dispositivi non-retina).

Esiste una convenzione che rende questa unità funzionante in modo uniforme sui vari dispositivi.

Percentuale

La percentuale, un'altra misura molto utile, ti permette di specificare i valori come percentuale della proprietà corrispondente dell'elemento genitore.

Esempio:

.genitore {
  width: 400px;
}

.figlio {
  width: 50%; /* = 200px */
}

Unità di misura del mondo reale

E poi ci sono unità di misura traslate dal mondo esterno. Per lo più inutili su schermo, possono essere utili per la stampa. Sono:

  • cm un centimetro (corrisponde a 37.8 pixel)
  • mm un millimetro (0.1cm)
  • q un quarto di millimetro
  • in un pollice o inch (corrisponde a 96 pixel)
  • pt un punto tipografico o point (1 inch = 72 point)
  • pc una pica (1 pica = 12 point)

Unità relative

  • em è il valore assegnato alla dimensione del carattere (font-size) di un elemento, perciò il suo esatto valore cambia tra gli elementi. Non cambia a seconda del font usato, ma solo in base alla dimensione. In tipografia è la misura della larghezza della lettera m.
  • rem è simile a em, ma invece di variare con la dimensione del carattere dell'elemento attuale, utilizza la dimensione del font dell'elemento root (html). Imposti la dimensione del font una volta, e rem sarà una misura uniforme su tutta la pagina.
  • ex è come em, ma invece di misurare la larghezza della m, misura l'altezza della lettera x. Può cambiare a seconda del font usato e della sua dimensione.
  • ch è come ex, ma invece di misurare l'altezza della x si basa sulla larghezza dello 0 (zero).

Unità viewport

  • vw l'unità viewport width rappresenta una percentuale della larghezza del viewport (area di visualizzazione). 50vw significa 50% della larghezza del viewport.
  • vh l'unità viewport height rappresenta una percentuale dell'altezza del viewport. 50vh significa 50% dell'altezza del viewport.
  • vmin l'unità viewport minimum rappresenta il minimo tra l'altezza o la larghezza in termini di percentuale. 30vmin è il 30% della larghezza o altezza corrente, a seconda di quale sia più piccola
  • vmax l'unità viewport maximum rappresenta il massimo tra altezza e larghezza in termini di percentuale. 30vmax è il30% della larghezza o dell'altezza corrente, a seconda di quale sia più grande

Unità frazionarie

Le fr sono unità frazionarie e vengono usate in CSS Grid per dividere lo spazio in frazioni.

Ne parleremo più avanti nel contesto di CSS Grid.

URL

Quando parliamo di immagini di sfondo, @import e altro, usiamo la funzione url() per caricare una risorsa:

div {
  background-image: url(test.png);
}

In questo caso, ho usato un URL relativo, che cerca il file nella cartella in cui è definito il file CSS.

Potrei salire di un livello

div {
  background-image: url(../test.png);
}

o andare in una cartella

div {
  background-image: url(subfolder/test.png);
}

oppure potrei caricare un file partendo dalla root del dominio in cui è ospitato il CSS:

div {
  background-image: url(/test.png);
}

O potrei usare un URL assoluto per caricare una risorsa esterna:

div {
  background-image: url(https://mysite.com/test.png);
}

CALC

La funzione calc() ti consente di svolgere operazioni matematiche di base su dei valori, ed è particolarmente utile quando hai bisogno di aggiungere o sottrarre un valore di lunghezza da una percentuale.

Ecco come funziona:

div {
    max-width: calc(80% - 100px)
}

Restituisce un valore di lunghezza, così può essere usata ovunque ti attendi un valore in pixel.

Puoi svolgere

  • addizioni usando +
  • sottrazioni usando -
  • moltiplicazioni usando *
  • divisioni usando /
Un avvertimento: con addizioni e sottrazioni, lo spazio intorno all'operatore è obbligatorio, altrimenti il funzionamento non è quello atteso.

Esempi:

div {
    max-width: calc(50% / 3)
}

div {
    max-width: calc(50% + 3px)
}

SFONDI

Lo sfondo di un elemento può essere cambiato usando varie proprietà CSS:

  • background-color
  • background-image
  • background-clip
  • background-position
  • background-origin
  • background-repeat
  • background-attachment
  • background-size

e la proprietà scorciatoia background, che ci permette di accorciare le definizioni e raggrupparle in una singola riga.

background-color accetta un valore di colore, che può essere una parola chiave colore o un valore rgb o hsl:

p {
  background-color: yellow;
}

div {
  background-color: #333;
}

Invece di usare un colore, puoi usare un'immagine come sfondo di un elemento, specificando la posizione dell'immagine con il suo URL:

div {
  background-image: url(image.png);
}

background-clip ti permette di determinare l'area usata dall'immagine o dal colore di sfondo. Il valore predefinito è border-box, che si estende fino al confine esterno del bordo.

Altri valori sono:

  • padding-box per estendere lo sfondo fino al confine del padding, senza il bordo
  • content-box per estendere lo sfondo fino al confine del contenuto, senza padding
  • inherit per applicare il valore del genitore

Quando usi un'immagine come sfondo puoi impostare la posizione in cui collocarla usando la proprietà background-position: left, right, center sono tutti valori validi per l'asse X, e top, bottom per l'asse Y:

div {
  background-position: top right;
}

Se l'immagine è più piccola del background, devi agire sulla proprietà background-repeat. Dovrebbe ripetersi sull'asse X (repeat-x), Y (repeat-y) o su tutti gli assi (repeat)? Quest'ultimo è il valore predefinito. Un altro valore è no-repeat.

background-origin ti permette di scegliere dove dovrebbe essere applicato lo sfondo: all'intero elemento includendo il padding (default) usando padding-box, all'intero elemento includendo il bordo usando border-box, all'elemento senza il padding usando content-box.

Con background-attachment possiamo fissare uno sfondo al viewport, in modo che non sia influenzato dallo scorrimento:

div {
  background-attachment: fixed;
}

Di default, il valore è scroll. Esiste un altro valore, local. Il modo migliore per visualizzarne il comportamento è questo Codepen.

L'ultima proprietà dello sfondo è background-size. Possiamo usare 3 parole chiave: auto, cover e contain. auto è il valore predefinito.

cover espande l'immagine fino a che l'intero elemento sia coperto dallo sfondo.

contain smette di espandere l'immagine di sfondo quando una delle dimensioni (x o y) copre interamente il lato più piccolo dell'immagine, in modo che sia completamente contenuta nell'elemento.

Puoi anche specificare un valore di lunghezza e, se lo fai, questo imposta la larghezza dell'immagine di sfondo (l'altezza viene definita automaticamente):

div {
  background-size: 100%;
}

Se specifichi 2 valori, uno è per la larghezza e il secondo per l'altezza:

div {
  background-size: 800px 600px;
}

La proprietà scorciatoia background permette di accorciare le definizioni e di raggrupparle in una sola riga.

Ecco un esempio:

div {
  background: url(bg.png) top left no-repeat;
}

Se usi un'immagine, puoi impostare un colore di ripiego nel caso l'immagine non venisse caricata:

div {
  background: url(image.png) yellow;
}

Puoi anche impostare un gradiente come sfondo:

div {
  background: linear-gradient(#fff, #333);
}

COMMENTI

Il CSS ti dà la possibilità di scrivere dei commenti in un file CSS o nel tag style nell'intestazione della pagina.

Il formato è /* questo è un commento */ nello stile dei commenti in C (o JavaScript, se preferisci).

Questo è un commento multi-riga. Finché non aggiungi il segno di chiusura */, tutte le righe trovate dopo quello di apertura sono considerate commenti.

Esempio:

#name { display: block; } /* Che bella regola! */

/* #name { display: block; } */

#name {
    display: block; /*
    color: red;
    */
}

Il CSS non ha commenti in linea, come // in C o JavaScript.

Fai attenzione – se aggiungi // prima di una regola, questa non sarà applicata, come se il commento avesse funzionato. In realtà, il CSS rileva un errore di sintassi e, per il modo in cui funziona, ignora la riga con l'errore e va dritto alla riga successiva.

Conoscere questo comportamento ti permette di scrivere di proposito commenti in linea, anche se devi fare attenzione perché non puoi aggiungere qualsiasi testo come in un blocco di commento.

Ad esempio:

// Che bella regola!
#name { display: block; }

In questo caso, per come funziona il CSS, la regola #name viene trasformata in un commento. Puoi trovare maggiori dettagli qui (risorsa in lingua originale inglese), se sei interessato. Per evitare di spararti su un piede, evita semplicemente di usare i commenti in linea e usa solo i blocchi di commento.

PROPRIETÀ PERSONALIZZATE

Negli ultimi anni, i preprocessori CSS hanno avuto molto successo. Per i progetti greenfield, era molto comune iniziare con Less o Sass. Ed è tutt'ora una tecnologia molto popolare.

Secondo me, i principali vantaggi di queste tecnologie sono i seguenti:

  • consentono di annidare i selettori
  • forniscono una semplice funzionalità di importazione
  • ti danno le variabili

Il moderno CSS ha nuove e potenti funzionalità chiamate proprietà CSS personalizzate, comunemente conosciute come variabili CSS.

Il CSS non è un linguaggio di programmazione come JavaScript, Python, PHP, Ruby o Go in cui le variabili sono essenziali per fare qualcosa di utile. Il CSS è davvero limitato in ciò che puoi fare, ed è costituito principalmente da una sintassi dichiarativa per dire al browser come mostrare una pagina HTML.

Ma una variabile è una variabile: un nome che fa riferimento a un valore, e le variabili in CSS aiutano a ridurre le ripetizioni e le incongruenze, mettendo in primo piano la definizione dei valori.

Inoltre, introduce una caratteristica unica che i preprocessori CSS non avranno mai: puoi accedere a una variabile CSS e cambiarne programmaticamente il valore usando JavaScript.

Le basi dell'utilizzo delle variabili

Una variabile CSS è definita con una sintassi speciale, anteponendo due trattini al nome (--nome-variabile) e poi due punti e il valore. In questo modo:

:root {
  --primary-color: yellow;
}

(parleremo di :root in seguito).

Puoi accedere al valore della variabile usando var():

p {
  color: var(--primary-color)
}

Il valore della variabile può essere qualsiasi valore CSS valido, ad esempio:

:root {
  --default-padding: 30px 30px 20px 20px;
  --default-color: red;
  --default-background: #fff;
}

Creare variabili all'interno di un elemento

Le variabili CSS possono essere definite all'interno di qualsiasi elemento. Alcuni esempi:

:root {
  --default-color: red;
}

body {
  --default-color: red;
}

main {
  --default-color: red;
}

p {
  --default-color: red;
}

span {
  --default-color: red;
}

a:hover {
  --default-color: red;
}

Ciò che cambia in questi diversi esempi è la visibilità (scope).

Visibilità delle variabili

Aggiungere variabili a un selettore le rende disponibili a tutti i suoi figli.

Nell'esempio precedente, hai visto l'utilizzo di :root per definire una variabile CSS:

:root {
  --primary-color: yellow;
}

:root è una pseudo-classe che identifica l'elemento "radice" di un albero.

Nel contesto di un documento HTML, usando il selettore :root si fa riferimento all'elemento html, eccetto che :root ha una specificità più elevata (ha la priorità).

Nel contesto di un'immagine SVG, :root punta al tag svg.

Aggiungere una proprietà CSS personalizzata a :root, la rende disponibile in tutti gli elementi della pagina.

Se vuoi aggiungere una variabile all'interno del selettore .container, sarà disponibile solo ai figli di .container:

.container {
  --secondary-color: yellow;
}

e non funzionerà usandola fuori da questo elemento.

Le variabili possono essere riassegnate:

:root {
  --primary-color: yellow;
}

.container {
  --primary-color: blue;
}

Fuori da .container, --primary-color sarà yellow, ma al suo interno sarà blue.

Puoi anche assegnare o sovrascrivere una variabile all'interno dell'HTML usando gli stili inline:

<main style="--primary-color: orange;">
  <!-- ... -->
</main>
Le variabili CSS seguono le normali regole CSS a cascata, con la precedenza definita secondo la specificità.

Interagire con il valore di una variabile CSS usando JavaScript

La cosa più bella delle variabili CSS è la possibilità di accedervi e modificarle usando JavaScript.

Ecco come puoi impostare il valore di una variabile usando del semplice JavaScript:

const element = document.getElementById('nome-id')
element.style.setProperty('--nome-variabile', 'un-valore')

Il codice qui sotto invece, può essere usato per accedere al valore di una variabile, nel caso la variabile sia definita in :root:

const styles = getComputedStyle(document.documentElement)
const value = String(styles.getPropertyValue('--nome-variabile')).trim()

Oppure, per applicare lo stile a uno specifico elemento, nel caso di una variabile impostata con una visibilità diversa:

const element = document.getElementById('nome-id')
const styles = getComputedStyle(element)
const value = String(styles.getPropertyValue('--nome-variabile')).trim()

Gestione dei valori non validi

Se a una variabile è assegnata a una proprietà che non accetta il valore della variabile, è considerata non valida.

Ad esempio, potresti passare un valore in pixel a una proprietà position, o un valore in rem a una proprietà di colore.

In questo caso, la riga è considerata non valida e viene ignorata.

Supporto browser

Il supporto browser per le variabili CSS è molto buono, secondo Can I Use.

Le variabili CSS sono destinate a durare e oggi puoi usarle se non hai bisogno di supportare Internet Explorer e le vecchie versioni di altri browser.

Se hai bisogno di supportare vecchi browser, puoi usare librerie come PostCSS o Myth, ma perderai la possibilità di interagire con le variabili attraverso JavaScript o gli strumenti per sviluppatori del browser, visto che vengono trasformate nel caro e vecchio CSS senza variabili (perdendo dunque la maggior parte del potere delle variabili CSS).

Le variabili CSS sono case sensitive

Questa variabile:

--width: 100px;

è diversa da questa:

--Width: 100px;

Matematica nelle variabili CSS

Per svolgere operazioni matematiche con le variabili CSS, hai bisogno di usare calc(), ad esempio:

:root {
  --default-left-padding: calc(10px * 2);
}

Media query con variabili CSS

Nulla di speciale qui. Le variabili CSS vengono applicate normalmente alle media query:

body {
  --width: 500px;
}

@media screen and (max-width: 1000px) and (min-width: 700px) {
  --width: 800px;
}

.container {
  width: var(--width);
}

Impostare un valore di ripiego per var()

var() accetta un secondo parametro, che è il valore di ripiego (fallback) predefinito quando il valore della variabile non è impostato:

.container {
  margin: var(--default-margin, 30px);
}

FONT

Agli albori del web c'era soltanto una manciata di caratteri tra cui scegliere.

Fortunatamente oggi puoi caricare ogni tipo di font sulle tue pagine.

Durante gli anni, il CSS ha guadagnato molte simpatiche funzionalità riguardo ai font.

La proprietà font è la scorciatoia per una serie di proprietà:

  • font-family
  • font-weight
  • font-stretch
  • font-style
  • font-size

Vediamo ognuna di esse, per poi parlare di font.

In seguito, parleremo di come caricare dei font personalizzati, usando @import o @font-face oppure caricando un foglio di stile di un font.

font-family

Imposta la famiglia di font di cui l'elemento farà uso.

Perché "famiglia"? Perché, come sappiamo, un font è in realtà composto di svariati sotto-font che forniscono tutti gli stili (grassetto, corsivo, light...) che ci servono.

Ecco un esempio dalla app Font Book del mio Mac – la famiglia di font Fira Code contiene al suo interno svariati appositi font:

3eSWEQuM-orkdVa7xATJ5p9sH2Te-clkilVI

Questa proprietà ti consente di selezionare uno specifico font, ad esempio:

body {
  font-family: Helvetica;
}

Puoi impostare più valori, in modo che la seconda opzione venga usata se la prima non può essere utilizzata per qualche ragione (se non viene trovata dalla macchina, o la connessione per scaricarla fallisce, ad esempio):

body {
  font-family: Helvetica, Arial;
}

Finora ho usato dei font specifici, quelli che chiamiamo font web-safe, dato che sono preinstallati su diversi sistemi operativi.

Si dividono in font Serif, Sans-Serif a Monospace. Ecco una lista di alcuni di alcuni dei più popolari:

Serif

  • Georgia
  • Palatino
  • Times New Roman
  • Times

Sans-Serif

  • Arial
  • Helvetica
  • Verdana
  • Geneva
  • Tahoma
  • Lucida Grande
  • Impact
  • Trebuchet MS
  • Arial Black

Monospace

  • Courier New
  • Courier
  • Lucida Console
  • Monaco

Puoi anche usarli tutti come proprietà font-family, ma non è garantito che siano presenti in ogni sistema. Ne esistono anche altri, con diversi livelli di supporto.

Puoi anche usare dei nomi generici:

  • sans-serif un font senza legature
  • serif un font con legature
  • monospace un font particolarmente adatto per il codice
  • cursive usato per simulare pezzi scritti a mano
  • fantasy il nome dice tutto

Questi vengono usati tipicamente alla fine di una definizione font-family, per dare un valore di ripiego nel caso nessun altro valore venga applicato:

body {
  font-family: Helvetica, Arial, sans-serif;
}

font-weight

Questa proprietà regola lo spessore di un font. Puoi usare questi valori predefiniti:

  • normal
  • bold
  • bolder (relativo all'elemento genitore)
  • lighter (relativo all'elemento genitore)

O usare le parole chiave numeriche:

  • 100
  • 200
  • 300
  • 400, corrisponde a normal
  • 500
  • 600
  • 700, corrisponde a bold
  • 800
  • 900

dove 100 è il font più leggero e 900 quello più marcato.

Alcuni di questi valori numerici potrebbero non applicarsi a un font, perché devono essere forniti dalla famiglia di font. Quando manca un valore, il CSS fa sì che quel numero corrisponda a un font marcato almeno quanto il precedente, quindi ci sono dei numeri che puntano allo stesso font.

font-stretch

Consente di scegliere una "faccia" del font più stretta o più larga, se disponibile.

Questo è importante: il font deve essere equipaggiato con diverse facce.

I valori permessi sono, dal più stretto al più ampio:

  • ultra-condensed
  • extra-condensed
  • condensed
  • semi-condensed
  • normal
  • semi-expanded
  • expanded
  • extra-expanded
  • ultra-expanded

font-style

Consente di applicare lo stile corsivo (italic) a un font:

p {
  font-style: italic;
}

Questa proprietà accetta anche i valori oblique e normal. C'è davvero poca differenza, se c'è, tra italic e oblique. Il primo è più semplice per me, dato che l'HTML offre già un elemento i che sta per italic.

font-size

Questa proprietà viene usata per determinare la dimensione di un font.

Puoi passarle due tipi di valori:

  1. un valore di lunghezza in px, em, rem ecc, o una percentuale
  2. una parola chiave predefinita

Nel secondo caso, i valori che puoi usare sono:

  • xx-small
  • x-small
  • small
  • medium
  • large
  • x-large
  • xx-large
  • smaller (relativamente all'elemento genitore)
  • larger (relativamente all'elemento genitore)

Utilizzo:

p {
  font-size: 20px;
}

li {
  font-size: medium;
}

font-variant

Questa proprietà era originariamente usata per cambiare il testo in maiuscoletto e ha solo 3 valori validi:

  • normal
  • inherit
  • small-caps

Maiuscoletto vuol dire che il testo viene presentato in lettere maiuscole ma di altezza inferiore a quella usuale.

font

La proprietà font ti permette di applicare differenti proprietà font insieme, riducendo lo spazio.

Occorre impostare almeno 2 proprietà, font-size e font-family, mentre le altre sono opzionali:

body {
  font: 20px Helvetica;
}

Se aggiungiamo le altre proprietà, devono essere inserite nell'ordine corretto.

Questo è l'ordine:

font: <font-stretch> <font-style> <font-variant> <font-weight> <font-size> <line-height> <font-family>;

Esempio:

body {
  font: italic bold 20px Helvetica;
}

section {
  font: small-caps bold 20px Helvetica;
}

Caricare font personalizzati usando @font-face

@font-face ti permette di aggiungere un nuovo nome di famiglia di font e di farlo corrispondere a un file che contiene il font.

Questo font sarà scaricato dal browser e usato nella pagina. Si tratta di una svolta fondamentale nella tipografia del web – ora possiamo usare qualsiasi font vogliamo.

Possiamo aggiungere delle dichiarazioni @font-face direttamente nel nostro CSS oppure linkare a un apposito CSS per importare il font.

Nel nostro file CSS possiamo anche usare @import per caricare quel file CSS.

Una dichiarazione @font-face contiene diverse proprietà che usiamo per definire il font, tra cui src, l'URI (uno o più URI) del font. Segue la regola della stessa origine (same-origin policy), che vuol dire che i font possono essere scaricati solo dall'origine attuale (dominio + porta + protocollo).

I font sono generalmente nei formati

  • woff (Web Open Font Format)
  • woff2 (Web Open Font Format 2.0)
  • eot (Embedded Open Type)
  • otf (OpenType Font)
  • ttf (TrueType Font)

Le seguenti proprietà ci permettono di definire le proprietà del font che stiamo per caricare, come visto in precedenza:

  • font-family
  • font-weight
  • font-style
  • font-stretch

Una nota sulle prestazioni

Naturalmente, caricare un font ha delle implicazioni riguardo alle prestazioni che dovresti considerare quando progetti una pagina.

TIPOGRAFIA

Abbiamo già parlato dei font, ma c'è anche altro per definire lo stile del testo.

In questa sezione, parleremo delle seguenti proprietà:

  • text-transform
  • text-decoration
  • text-align
  • vertical-align
  • line-height
  • text-indent
  • text-align-last
  • word-spacing
  • letter-spacing
  • text-shadow
  • white-space
  • tab-size
  • writing-mode
  • hyphens
  • text-orientation
  • direction
  • line-break
  • word-break
  • overflow-wrap

text-transform

Questa proprietà può cambiare le maiuscole/minuscole di un elemento.

Esistono 4 valori validi:

  • capitalize per rendere maiuscola la prima lettera di ogni parola
  • uppercase per rendere tutto il testo maiuscolo
  • lowercase per rendere tutto il testo minuscolo
  • none per disabilitare la trasformazione del testo, usato per  evitare di ereditare la proprietà

Esempio:

p {
  text-transform: uppercase;
}

text-decoration

Questa proprietà viene impostata per aggiungere delle decorazioni al testo, tra cui

  • underline
  • overline
  • line-through
  • blink
  • none

Esempio:

p {
  text-decoration: underline;
}

Puoi anche impostare lo stile della decorazione e il colore.

Esempio:

p {
  text-decoration: underline dashed yellow;
}

Valori di stile validi sono solid, double, dotted, dashed, wavy.

Puoi fare tutto in una riga oppure usare le proprietà specifiche:

  • text-decoration-line
  • text-decoration-color
  • text-decoration-style

Esempio:

p {
  text-decoration-line: underline;
  text-decoration-color: yellow;
  text-decoration-style: dashed;
}

text-align

Come impostazione predefinita, l'allineamento del testo ha il valore start, che vuol dire che il testo parte dall'inizio (start), origine 0, 0 del riquadro che lo contiene, ovvero in alto a sinistra, per le lingue scritte da sinistra a destra, e in alto a destra per quelle scritte da destra a sinistra.

I valori possibili sono start, end, left, right, center, justify (ottimo per avere uno spazio uniforme alla fine delle righe):

p {
  text-align: right;
}

vertical-align

Determina come sono allineati verticalmente gli elementi in linea.

Esistono diversi valori per questa proprietà. Prima possiamo assegnare un valore di lunghezza o percentuale. Vengono usati per allineare il testo in una posizione più alta o più bassa (usando un valore negativo) della linea di base dell'elemento genitore.

Poi abbiamo le parole chiave:

  • baseline (predefinito), allinea la linea di base a quella dell'elemento genitore
  • sub trasforma un elemento in pedice, simulando il risultato dell'elemento HTML sub
  • super trasforma un elemento in apice, simulando il risultato dell'elemento HTML sup
  • top allinea la parte superiore dell'elemento con la parte superiore della riga
  • text-top allinea la parte superiore dell'elemento con la parte superiore del font dell'elemento genitore
  • middle allinea il centro dell'elemento con il centro della riga del genitore
  • bottom allinea la parte inferiore dell'elemento con la parte inferiore della riga
  • text-bottom allinea la parte inferiore dell'elemento con la parte inferiore del font dell'elemento genitore

line-height

Consente di cambiare l'altezza di una riga. Ogni riga di testo ha una certa altezza del font, ma poi c'è uno spazio aggiuntivo tra  le righe. Quella è l'altezza della riga:

p {
  line-height: 0.9rem;
}

text-indent

Indenta la prima riga di un paragrafo impostando una lunghezza o una percentuale della larghezza del paragrafo:

p {
  text-indent: -10px;
}

text-align-last

Di default, l'ultima riga del paragrafo è allineata seguendo il valore di text-align. Usa questa proprietà per cambiare questo comportamento:

p {
  text-align-last: right;
}

word-spacing

Modifica la spaziatura tra ogni parola.

Puoi usare la parola chiave normal per resettare i valori ereditati o usare un valore di lunghezza:

p {
  word-spacing: 2px;
}

span {
  word-spacing: -0.2em;
}

letter-spacing

Modifica la spaziatura tra le lettere.

Puoi usare la parola chiave normal per resettare i valori ereditati oppure usare un valore di lunghezza:

p {
  letter-spacing: 0.2px;
}

span {
  letter-spacing: -0.2em;
}

text-shadow

Applica un'ombra al testo. Di default il testo non ha un'ombra.

Questa proprietà accetta un colore opzionale e una serie di valori che regolano:

  • lo scostamento dell'ombra sull'asse X rispetto al testo
  • lo scostamento dell'ombra sull'asse Y rispetto al testo
  • il raggio di sfocatura

Se il colore non è specificato, l'ombra sarà del colore del testo.

Esempio:

p {
  text-shadow: 0.2px 2px;
}

span {
  text-shadow: yellow 0.2px 2px 3px;
}

white-space

Definisce il modo in cui il CSS gestisce lo spazio vuoto, le nuove righe e le schede all'interno di un elemento.

Valori validi che comprimono lo spazio vuoto sono:

  • normal comprime lo spazio vuoto. Aggiunge nuove righe quando necessario se il testo raggiunge la fine del contenitore
  • nowrap comprime lo spazio vuoto. Non aggiunge una nuova riga quando il testo raggiunge la fine del contenitore ed elimina ogni interruzione di riga aggiunta al testo
  • pre-line comprime lo spazio vuoto. Aggiunge nuove righe quando necessario se il testo raggiunge la fine del contenitore.

Valori validi che mantengono lo spazio vuoto sono:

  • pre mantiene lo spazio vuoto. Non aggiunge una nuova riga quando il testo raggiunge la fine del contenitore, ma mantiene le interruzioni di riga aggiunte al testo
  • pre-wrap mantiene lo spazio vuoto. Aggiunge nuove righe quando necessario se il testo raggiunge la fine del contenitore

tab-size

Imposta la larghezza del carattere tab. Di default è 8 e puoi impostarlo su un valore intero, che determina quanto spazio occupa in caratteri, oppure su un valore di lunghezza:

p {
  tab-size: 2;
}

span {
  tab-size: 4px;
}

writing-mode

Definisce se le righe del testo sono disposte orizzontalmente o verticalmente e la direzione in cui procedono i blocchi.

I valori che puoi usare sono

  • horizontal-tb (predefinito)
  • vertical-rl il contenuto è disposto verticalmente. Le nuove righe sono messe a sinistra della precedente
  • vertical-lr il contenuto è disposto verticalmente. Le nuove righe sono messe a destra della precedente

hyphens

Determina se i trattini devono essere aggiunti automaticamente quando si va su una nuova riga.

I valori validi sono

  • none (predefinito)
  • manual aggiunge un trattino quando c'è già un trattino o un trattino nascosto (un carattere speciale)
  • auto aggiunge trattini quando determina che il testo può avere un trattino.

text-orientation

Quando writing-mode è nella modalità verticale, determina l'orientazione del testo.

Valori validi sono:

  • mixed è quello predefinito e se una lingua è verticale (come il giapponese), mantiene l'orientazione ruotando il testo scritto in linguaggi occidentali
  • upright orienta verticalmente tutto il testo
  • sideways orienta orizzontalmente tutto il testo

direction

Imposta la direzione del testo. Valori validi sono ltr e rtl:

p {
  direction: rtl;
}

word-break

Questa proprietà specifica come si interrompono le righe tra le parole.

  • normal (predefinito) significa che il testo viene interrotto solo tra le parole e non al loro interno
  • break-all il browser può spezzare una parola (ma non vengono aggiunti trattini)
  • keep-all sopprime il soft wrapping. Principalmente usato per i testi CJK (Cinese/Giapponese/Coreano).

Parlando di testi CJK, la proprietà line-break viene usata per determinare dove si interrompono le righe di testo. Non sono un esperto di queste lingue quindi eviterò di parlarne.

overflow-wrap

Se una parola è troppo lunga per entrare in una riga, può sforare dal contenitore.

Questa proprietà è anche conosciuta come word-wrap, sebbene non sia standard (ma funzione comunque come un alias)

Questo è il comportamento predefinito (overflow-wrap: normal;).

Possiamo usare:

p {
  overflow-wrap: break-word;
}

per interromperla all'esatta lunghezza della riga, oppure

p {
  overflow-wrap: anywhere;
}

se il browser vede che c'è la possibilità di spezzare la riga (soft wrap) prima. Non vengono aggiunti trattini, in ogni caso.

Questa proprietà è molto simile a word-break. Potremmo sceglierla per i linguaggi occidentali, mentre word-break offre un trattamento speciale per i linguaggi non occidentali.

MODELLO A SCATOLA

Ogni elemento CSS è essenzialmente una scatola. Ogni elemento è una generica scatola.

Il box model, o modello a scatola, spiega le dimensioni di un elemento in base a poche proprietà CSS.

Dall'interno verso l'esterno abbiamo:

  • area del contenuto
  • padding
  • bordo (border)
  • margine (margin)

Il modo migliore per visualizzare il modello a scatola è aprire gli strumenti per sviluppatori del browser e controllare come viene visualizzato:

xj9Q5XeqWTDKdl2roL0mkiHGXxRfGnAs4MhI

Qui puoi vedere come Firefox mi dice le proprietà di un elemento span che ho selezionato. Ho fatto click su di esso con il tasto destro, ho premuto "Ispeziona" e sono andato sul pannello "Layout" dei DevTools.

Lo spazio azzurro è l'area del contenuto, circondata dal padding, poi dal bordo e infine dal margine.

Di default, se imposti una larghezza (o altezza) per un elemento, sarà applicata all'area del contenuto. Tutti i calcoli per il padding, il bordo e il margine avvengono al di fuori di quel valore, quindi devi tenere a mente questo aspetto quando fai i tuoi conti.

In seguito vedrai come puoi cambiare questo comportamento usando box-sizing.

BORDI

Il bordo è uno strato sottile tra il padding e il margine. Modificando il bordo, puoi far apparire il perimetro degli elementi sullo schermo.

Puoi agire sui bordi usando queste proprietà:

  • border-style
  • border-color
  • border-width

La proprietà border può essere usata come scorciatoia per tutte queste proprietà.

border-radius viene usata per creare angoli arrotondati.

Hai anche la possibilità di usare immagini come bordi, grazie alla proprietà border-image e dalla sue separate proprietà specifiche:

  • border-image-source
  • border-image-slice
  • border-image-width
  • border-image-outset
  • border-image-repeat

Partiamo da border-style.

Lo stile dei bordi

La proprietà border-style ti consente di scegliere lo stile dei bordi. Le opzioni che puoi usare sono:

  • dotted
  • dashed
  • solid
  • double
  • groove
  • ridge
  • inset
  • outset
  • none
  • hidden
lCWsi0wfQU30QoiDD6GsvfRrWx-4DurGOMeX

Dai un'occhiata a questo Codepen per un esempio.

Il valore predefinito è none, quindi per far apparire il bordo devi cambiarlo in qualcos'altro. solid è una buona scelta il più delle volte.

Puoi impostare uno stile diverso per ogni lato usando le proprietà

  • border-top-style
  • border-right-style
  • border-bottom-style
  • border-left-style

oppure puoi usare border-style con più valori per definirli, usando il solito ordine Su-Destra-Giù-Sinistra:

p {
  border-style: solid dotted solid dotted;
}

Lo spessore del bordo

border-width viene usata per impostare la larghezza del bordo.

Puoi usare uno di questi valori:

  • thin
  • medium (il valore predefinito)
  • thick

o esprimere il valore in pixel, em o rem o qualsiasi altra unità di lunghezza valida.

Esempio:

p {
  border-width: 2px;
}

Puoi impostare la larghezza di ogni lato (Su-Destra-Giù-Sinistra) separatamente usando 4 valori:

p {
  border-width: 2px 1px 2px 1px;
}

oppure puoi usare le proprietà specifiche per ogni lato border-top-width, border-right-width, border-bottom-width, border-left-width.

Il colore del bordo

border-color viene usata per impostare il colore del bordo.

Se non imposti un colore, il bordo viene colorato in modo predefinito con il colore del testo dell'elemento.

Puoi passare a border-color qualsiasi valore di colore valido.

Esempio:

p {
  border-color: yellow;
}

Puoi impostare il colore di ogni lato (Su-Destra-Giù-Sinistra) separatamente usando 4 valori:

p {
  border-color: black red yellow blue;
}

oppure puoi usare le proprietà specifiche per ogni lato border-top-color, border-right-color, border-bottom-color, border-left-color.

La proprietà scorciatoia border

Queste 3 proprietà menzionate, border-width, border-style e border-color possono essere regolate usando le proprietà scorciatoia border.

Esempio:

p {
  border: 2px black solid;
}

Puoi usare anche le proprietà specifiche per ogni lato border-top, border-right, border-bottom, border-left.

Esempio:

p {
  border-left: 2px black solid;
  border-right: 3px red dashed;
}

Border radius

border-radius viene usata per arrotondare gli angoli dei bordi. Devi passare un valore che sarà usato come il raggio del cerchio utilizzato per smussare il bordo.

Utilizzo:

p {
  border-radius: 3px;
}

Puoi anche usare le proprietà specifiche per i lati border-top-left-radius, border-top-right-radius, border-bottom-left-radius, border-bottom-right-radius.

Usare immagini come bordo

Una cosa molto simpatica con i bordi è la possibilità di usare immagini per definirne lo stile, consentendoti di essere molto creativo.

Esistono 5 proprietà:

  • border-image-source
  • border-image-slice
  • border-image-width
  • border-image-outset
  • border-image-repeat

e la scorciatoia border-image. Qui non mi soffermerò oltre, dato che le immagini come bordo necessiterebbero di una trattazione più approfondita di quella che posso fare in questo piccolo capitolo. Consiglio questa lettura (risorsa in lingua originale inglese) per maggiori informazioni.

PADDING

La proprietà CSS padding è comunemente usata in CSS per aggiungere spazio alla parte interna di un elemento.

Ricorda:

  • margin aggiunge spazio all'esterno del bordo dell'elemento
  • padding aggiunge spazio all'interno del bordo dell'elemento

Proprietà padding specifiche

padding ha 4 proprietà correlate che alterano il padding di un singolo lato alla volta:

  • padding-top - su
  • padding-right - destra
  • padding-bottom - giù
  • padding-left - sinistra

L'uso di queste proprietà è molto semplice e non può essere confuso, ad esempio:

padding-left: 30px;
padding-right: 3em;

Usare la scorciatoia padding

padding è una scorciatoia per specificare più valori di padding allo stesso tempo, e si comporta in modo diverso a seconda di quanti valori vengono inseriti.

1 valore

L'uso di un singolo valore applica il padding a tutti i lati: top, right, bottom, left.

padding: 20px;

2 valori

Usando 2 valori il primo viene applicato a bottom & top, e il secondo a left & right.

padding: 20px 10px;

3 valori

Usando 3 valori il primo viene applicato a top, il secondo a left & right, e il terzo a bottom.

padding: 20px 10px 30px;

4 valori

Usando 4 valori il primo viene applicato a top, il secondo a right, il terzo a bottom, il quarto a left.

padding: 20px 10px 5px 0px;

Quindi l'ordine è top-right-bottom-left.

Valori accettati

padding accetta valori espressi in ogni tipo di unità di lunghezza, di cui i più comuni sono px, em, rem, ma ne esistono molti altri.

MARGINI

La proprietà CSS margin è comunemente usata in CSS per aggiungere spazio attorno a un elemento.

Ricorda:

  • margin aggiunge spazio all'esterno del bordo di un elemento
  • padding aggiunge spazio all'interno del bordo di un elemento

Proprietà margin specifiche

margin ha 4 proprietà correlate che alterano il margine di un singolo lato alla volta:

  • margin-top
  • margin-right
  • margin-bottom
  • margin-left

L'uso di queste proprietà è molto semplice e non può essere confuso, ad esempio:

margin-left: 30px;
margin-right: 3em;

Usare la scorciatoia margin

margin è una scorciatoia per specificare più margini allo stesso tempo, e a seconda del numero di valori inseriti si comporta in modo diverso.

1 valore

Usando un singolo valore, questo viene applicato a tutti i margini: top, right, bottom, left.

margin: 20px;

2 valori

Usando 2 valori, il primo viene applicato a bottom & top, e il secondo a left & right.

margin: 20px 10px;

3 valori

Usando 3 valori, il primo viene applicato a top, il secondo a left & right, il terzo a bottom.

margin: 20px 10px 30px;

4 valori

Usando 4 valori, il primo viene applicato a top, il secondo a right, il terzo a bottom, il quarto a left.

margin: 20px 10px 5px 0px;

Quindi l'ordine è top-right-bottom-left.

Valori accettati

margin accetta valori espressi in qualsiasi unità di lunghezza, di cui i più comuni sono px, em, rem, ma ne esistono molti altri.

Accetta anche valori percentuali e il valore speciale auto.

Usare auto per centrare elementi

auto può essere usato per selezionare automaticamente un margine ed è usato soprattutto per centrare un elemento, in questo modo:

margin: 0 auto;

Come detto sopra, usando 2 valori, il primo viene applicato a bottom & top, e il secondo a left & right.

Il modo moderno per centrare elementi è usare Flexbox, e la sua direttiva justify-content: center;.

I vecchi browser naturalmente non implementano Flexbox e se hai bisogno di supportarli, margin: 0 auto; è una buona scelta.

Usare un margine negativo

margin è l'unica proprietà relativa alle dimensioni che può avere un valore negativo. Ed è anche estremamente utile. Impostare un margine superiore negativo fa sì che l'elemento si sposti sopra l'elemento che lo precede, e con un valore abbastanza negativo si sposterà fuori dalla pagina.

Un margine inferiore negativo sposta l'elemento dopo di esso.

Un margine destro negativo fa espandere il contenuto dell'elemento oltre la dimensione ammessa.

Un margine sinistro negativo sposta l'elemento sopra l'elemento che lo precede, e con un valore abbastanza negativo si sposterà fuori dalla pagina.

BOX SIZING

Il comportamento predefinito dei browser nel calcolo della larghezza di un elemento è di applicare la larghezza e l'altezza calcolate all'area del contenuto, senza prendere in considerazione padding e margini.

Questo approccio si è dimostrato essere alquanto complicato per lavorare.

Puoi cambiare questo comportamento impostando la proprietà box-sizing.

La proprietà box-sizing è di grande aiuto. Ha due valori:

  • border-box
  • content-box

content-box è il valore predefinito, quello che abbiamo avuto per anni prima che box-sizing prendesse forma.

border-box è il valore nuovo e meraviglioso che stavamo cercando. Se lo imposti per un elemento:

.my-div {
  box-sizing: border-box;
}

il calcolo di larghezza e altezza include padding e bordo. Solo il margine viene lasciato fuori, il che è ragionevole dato che nella nostra mente lo vediamo tipicamente come una cosa separata: il margine è al di fuori della scatola.

Questa proprietà è un piccolo cambiamento ma ha un grande impatto. CSS Tricks ha persino indetto l'international box-sizing awareness day, tanto per dire, ed è consigliato applicarla a tutti gli elementi sulla pagina, pronta all'uso, così:

*, *:before, *:after {
  box-sizing: border-box;
}

DISPLAY

La proprietà display di un oggetto determina come viene presentato nel browser.

È una proprietà molto importante e probabilmente quella con il maggior numero di valori che puoi usare.

Questi valori comprendono:

  • block
  • inline
  • none
  • contents
  • flow
  • flow-root
  • table (e tutti quelli table-*)
  • flex
  • grid
  • list-item
  • inline-block
  • inline-table
  • inline-flex
  • inline-grid
  • inline-list-item

più altri che userai difficilmente, come ruby.

Scegliere uno di questi altererà in modo considerevole il comportamento del browser con l'elemento e i suoi figli.

In questa sezione analizzeremo i valori più importanti e non trattati altrove:

  • block
  • inline
  • inline-block
  • none

Nei capitoli successivi vedremo alcuni degli altri, tra cui table, flex e grid.

inline

Inline è il valore predefinito di display per tutti gli elementi in CSS.

Tutti i tag HTML vengono visualizzati come inline, eccetto alcuni elementi come div, p e section, che vengono impostati come block dallo user agent (il browser).

Gli elementi inline non hanno alcun margine o padding applicati.

Lo stesso vale per altezza e larghezza.

Puoi aggiungerli, ma l'aspetto nella pagina non cambierà — sono calcolati e applicati automaticamente dal browser.

inline-block

Simile a inline, ma con inline-block width e height vengono applicate come specifichi.

block

Come menzionato, normalmente gli elementi sono visualizzati come inline, con l'eccezione di alcuni elementi, tra cui:

  • div
  • p
  • section
  • ul

che sono impostati come block dal browser.

Con display: block, gli elementi sono impilati gli uni sugli altri verticalmente e ogni elemento occupa il 100% della pagina.

I valori assegnati alle proprietà width e height sono rispettati, se li imposti, insieme a margin e padding.

none

Usare display: none fa scomparire un elemento. È ancora lì nell'HTML, ma non è visibile nel browser.

POSIZIONAMENTO

Il posizionamento è ciò che determina dove gli elementi appaiono sullo schermo e come appaiono.

Puoi spostare gli elementi in giro e posizionarli esattamente dove vuoi.

In questa sezione, vedremo anche come cambiano le cose su una pagina in base a come gli elementi in diverse posizioni interagiscono tra di loro.

Abbiamo una proprietà CSS principale: position.

Può assumere questi 5 valori:

  • static
  • relative
  • absolute
  • fixed
  • sticky

Posizionamento statico

È il valore predefinito per un elemento. Gli elementi con posizionamento statico sono mostrati nel normale flusso della pagina.

Posizionamento relativo

Se imposti position: relative su un elemento, sei in grado di posizionarlo secondo uno spostamento impostando le proprietà:

  • top
  • right
  • bottom
  • left

che vengono chiamate proprietà offset. Accettano un valore di lunghezza o una percentuale.

Prendi questo esempio che ho creato su Codepen. Ho creato un contenitore genitore (parent), un contenitore figlio (child) e una scatola interna (box) con del testo:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>Test</p>
    </div>
  </div>
</div>

con un po' di CSS per dare colori e padding, ma senza influenzare il posizionamento:

.parent {
  background-color: #af47ff;
  padding: 30px;
  width: 300px;
}

.child {
  background-color: #ff4797;
  padding: 30px;
}

.box {
  background-color: #f3ff47;
  padding: 30px;
  border: 2px solid #333;
  border-style: dotted;
  font-family: courier;
  text-align: center;
  font-size: 2rem;
}

Ecco il risultato:

gtXUfjyrczqxDqdfrjJyec58o9ru6CqGGCFD

Puoi provare ad aggiungere a .box qualsiasi altra proprietà che ho menzionato precedentemente (top, right, bottom, left) e non accadrà nulla. La posizione è static.

Se impostiamo position: relative per il box, sulle prime sembra non cambiare nulla. Ma adesso l'elemento è in grado di muoversi usando le proprietà top, right, bottom, left, e ora puoi variare la sua posizione relativamente all'elemento che lo contiene.

Ad esempio:

.box {
  /* ... */
  position: relative;
  top: -60px;
}
aYTcDVhCB9-CazlQrWrPyfxMpr3TThT0V-ho

Un valore negativo di top farà spostare il box in alto relativamente al suo contenitore.

Oppure

.box {
  /* ... */
  position: relative;
  top: -60px;
  left: 180px;
}
5ePc6ALKZV0fubpagz0OzfPBCzctqPAJY81p

Nota come lo spazio che è occupato dal box resta invariato nel contenitore, come se fosse ancora al suo posto.

Un'altra proprietà che adesso funzionerà è z-index, per alterare il posizionamento sull'asse z. Ne parleremo più avanti.

Posizionamento assoluto

Impostare position: absolute su un elemento lo rimuoverà dal flusso del documento.

Ricordi che con il posizionamento relativo abbiamo notato che lo spazio originalmente occupato dall'elemento era rimasto invariato anche dopo lo spostamento?

Con il posizionamento assoluto, non appena impostiamo position: absolute su .box, il suo spazio originario collassa e soltanto l'origine (coordinate x, y) resta la stessa.

.box {
  /* ... */
  position: absolute;
}
B4aFUpYab0eSO-LUQKAu2Vmbi-wnFA8qFOHm

Adesso possiamo spostare il box in giro a nostro piacimento usando le proprietà top, right, bottom, left:

.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}
NHw-ZkR2lzBsPyb9gSYTyuYGreSvedNPsJ7J

oppure

.box {
  /* ... */
  position: absolute;
  top: 140px;
  left: 50px;
}
QOYrWkDjiNv7ODZ9WtYCBVEnJf5oZwGfombH

Le coordinate sono relative al contenitore più vicino che non è static.

Ciò vuol dire che se aggiungiamo position: relative all'elemento .child e impostiamo top e left su 0, il box non sarà posizionato nel margine superiore sinistro della finestra, ma sarà posizionato nelle coordinate 0, 0 di .child:

.child {
  /* ... */
  position: relative;
}

.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}
1FB8qKtiZgmxtp7xjd6UU7CW573XRxTrZlNc

Ed ecco, come abbiamo già visto, .child in posizionamento statico (predefinito):

.child {
  /* ... */
  position: static;
}

.box {
  /* ... */
  position: absolute;
  top: 0px;
  left: 0px;
}
eF4yC5dRIkcyezTcVUCbG36sfxOVurQX2L38

Come per il posizionamento relativo, puoi usare z-index per cambiare il posizionamento sull'asse z.

Posizionamento fisso

Come per il posizionamento assoluto, quando a un elemento è assegnato position: fixed, viene rimosso dal flusso della pagina.

La differenza con il posizionamento assoluto è che gli elementi sono sempre posizionati in base alla finestra, invece che rispetto al primo contenitore non statico.

.box {
  /* ... */
  position: fixed;
}
Ium4uJdPRXPpp-gAVsMMWveviu6HY-g0nUYA
.box {
  /* ... */
  position: fixed;
  top: 0;
  left: 0;
}
k3-LecCC6WXUjssKdQ9u9w70EZSh3hzK3iFY

Un'altra grande differenza è che gli elementi non sono influenzati dallo scorrimento. Una volta che posizioni da qualche parte un elemento fisso, lo scorrimento non lo rimuove dalla parte visibile della pagina.

Posizionamento sticky

Mentre i valori qui sopra sono in circolazione da molto tempo, questo è stato aggiunto recentemente ed è ancora relativamente non supportato (vedi caniuse.com).

Il componente UITableView iOS è ciò che mi viene in mente pensando a position: sticky. Hai presente quando scorri la lista dei contatti e la prima lettera resta bloccata in cima, per farti sapere che stai vedendo i contatti con quella specifica lettera?

Usavamo JavaScript per mimare questo effetto, ma questo è l'approccio adottato dal CSS per consentirlo in modo nativo.

FLOAT E CLEAR

Float è stato un argomento molto importante in passato.

Veniva usato per un sacco di trucchetti e utilizzi creativi, visto che era uno dei pochi modi, insieme alla tabelle, per realizzare alcuni layout. Nel passato era comune usare float, ad esempio, per mostrare la barra laterale sul lato sinistro dello schermo e aggiungere del margine al contenuto principale.

Fortunatamente i tempi sono cambiati e oggi abbiamo Flexbox e Grid per darci una mano con i layout, così float è tornata al suo scopo originale: posizionare il contenuto su un lato dell'elemento contenitore e rendere visibili i suoi fratelli intorno ad esso.

La proprietà float supporta 3 valori:

  • left
  • right
  • none (predefinito)

Diciamo di avere un box che contiene un paragrafo con del testo, e il paragrafo contiene un'immagine.

Ecco il codice:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>This is some random paragraph and an image. <img src="https://via.placeholder.com/100x100" /> The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text.
      </p>
    </div>
  </div>
</div>

.parent {
  background-color: #af47ff;
  padding: 30px;
  width: 500px;
}

.child {
  background-color: #ff4797;
  padding: 30px;
}

.box {
  background-color: #f3ff47;
  padding: 30px;
  border: 2px solid #333;
  border-style: dotted;
  font-family: courier;
  text-align: justify;
  font-size: 1rem;
}

e come appare visivamente:

fx5ZaCoCalyWSNeIkNi6044e5uEPPlQVupJD

Come puoi vedere, il normale flusso predefinito considera l'immagine inline e le fa spazio sulla riga stessa.

Se aggiungiamo all'imagine float: left e del padding:

img {
  float: left;
  padding: 20px 20px 0px 0px;
}

Ecco il risultato:

Yftt6zI7UBrNYY30BapoEr3BAtiVCx80M4Eq

e questo è ciò che otteniamo applicando float: right, regolando il padding di conseguenza:

img {
  float: right;
  padding: 20px 0px 20px 20px;
}
WORQNScMck67c42LH0cfbiZJmzNnGzWde1Au

Un elemento con float viene rimosso dal normale flusso della pagina e gli altri contenuti fluiscono intorno a esso.

Guarda questo esempio su Codepen

Non sei costretto a usarlo solo sulle immagini. In questo caso abbiamo sostituito l'immagine con un elemento span:

<div class="parent">
  <div class="child">
    <div class="box">
      <p>This is some random paragraph and an image. <span>Some text to float</span> The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text. The image is in the middle of the text.
      </p>
    </div>
  </div>
</div>

span {
  float: right;
  margin: 20px 0px 20px 20px;
  padding: 10px;
  border: 1px solid black
}

e questo è il risultato:

Pe0oVfgmeHF7Rheb4hPwXTaq5AZ1939rMeBy

Clear

Cosa accade se usi float su più elementi?

Se trovano altre immagini con float, di default si affiancano tra di loro orizzontalmente, finché non c'è più spazio e iniziano ad andare su una nuova riga.

Diciamo di avere 3 immagini inline in un tag p:

15-LCn0BOSVAVMraLSiNzWpP-oWBiEKIGULW

Se aggiungiamo float: left alle immagini:

img {
  float: left;
  padding: 20px 20px 0px 0px;
}

ecco cosa otterremo:

JGZ7LTxKux1nKWIISdzIPgb2jzxcqpifbxIx

Se aggiungiamo clear: left alle immagini, saranno impilate verticalmente invece che disposte orizzontalmente:

9J-ggQAlJFZ4C1hUbnpD74FcjuKpS960LABv

Ho usato il valore left per clear. Accetta:

  • left per sinistra
  • right per destra
  • both per entrambe
  • none (predefinito) disabilita clear

Z-INDEX

Quando abbiamo parlato del posizionamento, ho menzionato l'utilizzo della proprietà z-index per controllare il posizionamento degli elementi sull'asse Z.

È molto utile quando hai più elementi che si sovrappongono gli uni sugli altri e devi decidere quale deve essere visibile, in quanto più vicino all'utente, e quali devono essere nascosti dietro di esso.

Questa proprietà prende un numero (senza decimali) e lo utilizza per calcolare quale elemento deve apparire più vicino all'utente, sull'asse Z.

Più alto è il valore di z-index, più vicino all'utente si trova un elemento.

Per decidere quale elemento dovrebbe essere visibile e quale dovrebbe essere posizionato dietro di esso, il browser effettua il calcolo sulla base del valore di z-index.

Il valore predefinito è auto, una parola chiave speciale. Usando auto, l'asse Z è determinato dalla posizione dell'elemento HTML nella pagina – l'ultimo fratello appare per primo, in quanto definito per ultimo.

Di default gli elementi hanno il valore static per la proprietà position. In questo caso, la proprietà z-index non fa alcuna differenza – position deve essere impostata su absolute, relative o fixed affinché funzioni.

Esempio:

.my-first-div {
    position: absolute;
    top: 0;
    left: 0;
    width: 600px;
    height: 600px;
    z-index: 10;
}

.my-second-div {
    position: absolute;
    top: 0;
    left: 0;
    width: 500px;
    height: 500px;
    z-index: 20;
}

L'elemento con la classe .my-second-div sarà visualizzato e dietro di lui .my-first-div.

Qui abbiamo usato 10 e 20, ma puoi usare qualsiasi numero. Anche numeri negativi. È comune scegliere numeri non consecutivi, in modo da poter posizionare degli elementi nel mezzo. Se invece utilizzi numeri consecutivi, avrai bisogno di ricalcolare lo z-index coinvolto nel posizionamento di ogni elemento.

CSS GRID

CSS Grid è il nuovo arrivato nella città del CSS, e nonostante non sia ancora completamente supportato da tutti i browser, sarà il sistema alla base dei layout del futuro.

Fondamentalmente, CSS Grid è un nuovo approccio per creare dei layout usando il CSS.

Dai un'occhiata alla pagina CSS Grid Layout su caniuse.com (https://caniuse.com/#feat=css-grid) per trovare quali browser lo supportano attualmente. Nell'aprile 2019, al momento della scrittura di questo manuale, tutti i maggiori browser (eccetto IE, che non lo ha mai supportato) stanno già supportando questa tecnologia, raggiungendo il 92% di tutti gli utenti.

CSS Grid non è un concorrente di Flexbox. Interagiscono e collaborano in layout complessi, perché CSS Grid lavora in 2 dimensioni (righe E colonne), mentre Flexbox lavora in una sola dimensione (righe O colonne).

Costruire layout per il web è tradizionalmente un argomento complicato.

Non mi addentrerò nei dettagli di questa complessità, in quanto si tratta di un argomento a sé stante, ma puoi ritenerti una persona davvero fortunata dato che al giorno d'oggi hai a disposizione 2 strumenti molto potenti e ben supportati:

  • CSS Flexbox
  • CSS Grid

Questi sono i 2 strumenti con cui costruire i layout del web del futuro.

A meno che tu non debba supportare vecchi browser come IE8 e IE9, non c'è ragione per crearsi problemi con cose come:

  • layout di tabelle
  • float
  • trucchetti clearfix
  • trucchetti display: table

In questa guida, c'è tutto ciò che ti serve sapere per passare dal non avere alcuna conoscenza di CSS Grid a essere un utente competente.

Le basi

Il layout CSS Grid viene attivato su un elemento contenitore (che può essere un div o qualsiasi altro tag) impostando display: grid.

Come per flexbox, puoi definire alcune proprietà sul contenitore e alcune proprietà su singoli elementi della griglia.

Queste proprietà combinate, determineranno l'aspetto finale della griglia.

Le proprietà più semplici per il contenitore sono grid-template-columns e grid-template-rows.

grid-template-columns e grid-template-rows

Queste proprietà definiscono il numero di colonne e righe della griglia, e regolano anche la larghezza di ogni colonna/riga.

Il seguente snippet definisce una griglia di 4 colonne, ognuna larga 200 px, e 2 righe, ognuna alta 300 px.

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
}
LgbgchKoiffQNAqLtBYVbPsLJMKiWB3XWvCP

Ecco un altro esempio di una griglia con due colonne e due righe:

.container {
  display: grid;
  grid-template-columns: 200px 200px;
  grid-template-rows: 100px 100px;
}
sdVnLwfTJmY1alewU41wNxRMZ827XK07quWq

Dimensioni automatiche

Spesso potresti avere una dimensione fissa per l'intestazione, il piè di pagina e il contenuto principale, che è variabile in altezza, a seconda della sua lunghezza. In questo caso puoi usare la parola chiave auto:

.container {
  display: grid;
  grid-template-rows: 100px auto 100px;
}

Dimensioni diverse di righe e colonne

Negli esempi precedenti, abbiamo creato griglie regolari usando lo stesso valore per le righe e lo stesso valore per le colonne.

Puoi specificare qualsiasi valore per ogni riga/colonna, per creare tanti design diversi:

.container {
  display: grid;
  grid-template-columns: 100px 200px;
  grid-template-rows: 100px 50px;
}
h5vifpz6IUZQbWCzX4YvJjOhLojgzgP2F-AN

Un altro esempio:

.container {
  display: grid;
  grid-template-columns: 10px 100px;
  grid-template-rows: 100px 10px;
}
GGCFboj9Z6YQz8jvB69KmslqKz00sLuca843

Aggiungere spazio tra le celle

Se non specificato, non c'è spazio tra le celle.

Puoi aggiungere dello spazio usando queste proprietà:

  • grid-column-gap
  • grid-row-gap

o con la sintassi scorciatoia grid-gap.

Esempio:

.container {
  display: grid;
  grid-template-columns: 100px 200px;
  grid-template-rows: 100px 50px;
  grid-column-gap: 25px;
  grid-row-gap: 25px;
}
ivVtIubdZG3BpFfoASpFy4EMJG1kXeiCx3zP

Lo stesso layout con la scorciatoia:

.container {
  display: grid;
  grid-template-columns: 100px 200px;
  grid-template-rows: 100px 50px;
  grid-gap: 25px;
}

Disporre elementi su righe e/o colonne multiple

Ogni elemento ha la possibilità di occupare più di una cella nella riga ed espandersi orizzontalmente o verticalmente per prendere più spazio, rispettando le proporzioni della griglia impostata sul contenitore.

Queste sono le proprietà che possiamo usare a questo scopo:

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end

Esempio:

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
}

.item1 {
  grid-column-start: 2;
  grid-column-end: 4;
}

.item6 {
  grid-column-start: 3;
  grid-column-end: 5;
}
JrzZm5o6SkpvGiKZo6v8XmRDAfpajBt6mym4

I numeri corrispondono alle linee verticali che separano ogni colonna, partendo da 1:

JdCCwzrGzvd1O68dBAqIHSWh4hMbM6ttuJ8Z

Lo stesso principio si applica a grid-row-start e grid-row-end, eccetto che questa volta, invece di occupare più colonne, una cella occupa più righe.

Sintassi scorciatoia

Queste proprietà possiedono una sintassi scorciatoia fornita da:

  • grid-column
  • grid-row

L'utilizzo è semplice, ecco come replicare il layout precedente:

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
}

.item1 {
  grid-column: 2 / 4;
}

.item6 {
  grid-column: 3 / 5;
}

Un altro approccio è impostare le colonne o righe iniziali e poi impostare quante ne dovrebbero essere occupate usando span:

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
}

.item1 {
  grid-column: 2 / span 2;
}

.item6 {
  grid-column: 3 / span 2;
}

Altre configurazioni

Usare le frazioni

Specificare l'esatta larghezza di ogni colonna o riga non è sempre ideale.

Una frazione è un'unità di spazio.

Il seguente esempio divide una griglia in 3 colonne con la stessa larghezza, ognuna 1/3 dello spazio disponibile.

.container {
  grid-template-columns: 1fr 1fr 1fr;
}

Usare percentuali e rem

Puoi anche usare percentuali, e mischiare frazioni, pixel, rem e percentuali:

.container {
  grid-template-columns: 3rem 15% 1fr 2fr
}

Usare repeat()

repeat() è una funzione speciale che prende un numero che indica le volte in cui una riga/colonna deve essere ripetuta, e la sua lunghezza.

Se ogni colonna ha la stessa larghezza, puoi specificare il layout usando la sintassi:

.container {
  grid-template-columns: repeat(4, 100px);
}

Questo crea 4 colonne con la stessa larghezza.

Oppure usando le frazioni:

.container {
  grid-template-columns: repeat(4, 1fr);
}

Specificare la larghezza minima di una riga

Caso di utilizzo comune: una barra laterale che non si comprime mai più di un certo valore di pixel quando ridimensioni la finestra.

Ecco un altro esempio in cui la barra laterale occupa 1/4 della schermo e mai meno di 200 px:

.container {
  grid-template-columns: minmax(200px, 3fr) 9fr;
}

Puoi anche impostare solo un valore massimo usando la parola chiave auto:

.container {
  grid-template-columns: minmax(auto, 50%) 9fr;
}

o solo un valore minimo:

.container {
  grid-template-columns: minmax(100px, auto) 9fr;
}

Posizionare elementi usando grid-template-areas

Di default gli elementi sono posizionati nella griglia in base all'ordine nella struttura HTML.

Usando grid-template-areas puoi definire delle aree per spostarli nella griglia e disporre un elemento su più righe/colonne invece di usare grid-column.

Ecco un esempio:

<div class="container">
  <main>
    ...
  </main>
  <aside>
    ...
  </aside>
  <header>
    ...
  </header>
  <footer>
    ...
  </footer>
</div>

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
  grid-template-areas:
    "header header header header"
    "sidebar main main main"
    "footer footer footer footer";
}
main {
  grid-area: main;
}
aside {
  grid-area: sidebar;
}
header {
  grid-area: header;
}
footer {
  grid-area: footer;
}

Malgrado il loro ordine originario, gli elementi sono posizionati dove definito da grid-template-areas, in base alla proprietà grid-area ad essi associata.

Aggiungere celle vuote nelle aree di template

Puoi impostare una cella vuota usando un punto . invece di un nome di area in grid-template-areas:

.container {
  display: grid;
  grid-template-columns: 200px 200px 200px 200px;
  grid-template-rows: 300px 300px;
  grid-template-areas:
    ". header header ."
    "sidebar . main main"
    ". footer footer .";
}

Riempire la pagina con una griglia

Puoi far estendere la griglia in modo da riempire la pagina con fr:

.container {
  display: grid;
  height: 100vh;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}

Ecco un semplice esempio dell'uso di CSS Grid per creare il layout di un sito che contiene un'intestazione in cima, una parte principale con una barra laterale sulla sinistra e il contenuto a destra, e infine un piè di pagina.

M8qvpAE1DS6BoPXyfpb2VWAEbz2C8U4W587t

Ecco il markup:

<div class="wrapper">
  <header>Header</header>
  <article>
    <h1>Welcome</h1>
    <p>Hi!</p>
  </article>
  <aside><ul><li>Sidebar</li></ul></aside>
  <footer>Footer</footer>
</div>

e il CSS:

header {
  grid-area: header;
  background-color: #fed330;
  padding: 20px;
}
article {
  grid-area: content;
  background-color: #20bf6b;
  padding: 20px;
}
aside {
  grid-area: sidebar;
  background-color: #45aaf2;
}
footer {
  padding: 20px;
  grid-area: footer;
  background-color: #fd9644;
}
.wrapper {
  display: grid;
  grid-gap: 20px;
  grid-template-columns: 1fr 3fr;
  grid-template-areas:
    "header  header"
    "sidebar content"
    "footer  footer";
}

Ho aggiunto alcuni colori per renderlo più gradevole, ma in sostanza assegna ad ogni tag un nome grid-area, che viene usato nella proprietà grid-template-areas in .wrapper.

Quando il layout è più ristretto possiamo mettere la barra laterale al di sotto del contenuto usando una media query:

@media (max-width: 500px) {
  .wrapper {
    grid-template-columns: 4fr;
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
  }
}

Vedi su CodePen

Queste erano le basi di CSS Grid. Ci sono molte cose che non ho incluso in questa introduzione, ma volevo rendere le cose semplici, in modo da consentirti di iniziare a usare questo nuovo sistema di layout senza sentirti sopraffatto.

FLEXBOX

Flexbox, anche detto Flexible Box Module, è uno dei due sistemi di layout moderni, insieme a CSS Grid.

In confronto a CSS Grid (che è bidimensionale), flexbox è un modello di layout monodimensionale. Controlla il layout in base a una riga o una colonna, ma non a entrambe allo stesso tempo.

L'obiettivo principale di flexbox è consentire agli elementi di riempire l'intero spazio offerto dal loro contenitore, a seconda delle regole impostate.

A meno che tu abbia bisogno di supportare vecchi browser come IE8 e IE9, Flexbox è lo strumento che ti permette di dimenticarti di

  • layout di tabelle
  • float
  • trucchetti clearfix
  • trucchetti display: table

E adesso tuffiamoci su flexbox e diventiamo dei maestri in poco tempo.

Supporto browser

Al momento della scrittura (Feb 2018), è supportato dal 97.66% degli utenti. Tutti i browser più importanti lo hanno implementato per anni, e persino vecchi browser (tra cui IE10+) sono coperti:

pAsJcNUmJljKeifKY7DSA8-LQasyo2vsgOoW

Mentre dobbiamo aspettare ancora qualche anno per metterci in pari con CSS Grid, Flexbox è una tecnologia più vecchia e può essere usata proprio adesso.

Attivare Flexbox

Il layout flexbox viene applicato a un contenitore impostando

display: flex;

oppure

display: inline-flex;

Il contenuto all'interno del contenitore sarà allineato usando flexbox.

Proprietà del contenitore

Alcune proprietà flexbox si applicano al contenitore, che determina le regole generali per i suoi elementi. Si tratta di

  • flex-direction
  • justify-content
  • align-items
  • flex-wrap
  • flex-flow

Allineare righe o colonne

La prima proprietà che vedremo, flex-direction, determina se il contenitore  dovrebbe allineare i suoi elementi in righe o colonne:

  • flex-direction: row posiziona gli elementi su una riga, nella direzione del testo (da sinistra a destra per i Paesi occidentali)
  • flex-direction: row-reverse posiziona gli elementi come row, ma nel verso opposto
  • flex-direction: column posiziona gli elementi su una colonna, dall'alto in basso
  • flex-direction: column-reverse posiziona gli elementi su una colonna, proprio come column ma nel verso opposto
o26IgBk91Cjdfe8h-uAl-NAULk6k5fUjTI8o

Allineamento verticale e orizzontale

Di default gli elementi partono dalla sinistra se flex-direction è row, e dall'alto se flex-direction è column.

lgTI1ZtxbWha-5GyAWbTNrmOhe03ikkpo-Gx

Puoi cambiare questo comportamento usando justify-content per variare l'allineamento orizzontale e align-items per variare l'allineamento verticale.

Cambiare l'allineamento orizzontale

justify-content ha 5 possibili valori:

  • flex-start: allinea al lato sinistro del contenitore.
  • flex-end: allinea al lato destro del contenitore.
  • center: allinea al centro del contenitore.
  • space-between: determina una spaziatura uguale tra gli elementi.
  • space-around: determina una spaziatura uguale attorno agli elementi.
3eA5Rgtjp0xnyWoQ5v5e1aWIbgmS8YgWzgdm

Cambiare l'allineamento verticale

align-items ha 5 possibili valori:

  • flex-start: allinea in cima al contenitore.
  • flex-end: allinea in fondo al contenitore.
  • center: allinea al centro del contenitore verticalmente.
  • baseline: allinea alla linea di base del contenitore.
  • stretch: gli elementi sono estesi fino a riempire il contenitore.
1pQRvAAzAtBRjO8UI8-zpoa8rL51uKkKklZR

Una nota su baseline:

baseline sembra simile a flex-start in questo esempio, perché le scatole sono troppo semplici. Per avere un esempio più utile, dai un'occhiata a questo Codepen, ottenuto dal fork di un Pen originalmente creato da Martin Michálek. Come puoi vedere, le dimensioni degli elementi sono allineate.

Wrap

Di default, gli elementi in un contenitore flexbox restano su una singola linea, rimpicciolendosi per adattarsi al contenitore.

Per forzare gli elementi a disporsi su più linee, usa flex-wrap: wrap. In questo modo, gli elementi saranno distribuiti secondo l'ordine impostato da flex-direction. Usa flex-wrap: wrap-reverse per invertire quest'ordine.

La proprietà scorciatoia chiamata flex-flow ti permette di specificare flex-direction e flex-wrap in una sola riga, aggiungendo prima il valore di flex-direction, seguito dal valore di flex-wrap, ad esempio: flex-flow: row wrap.

Proprietà che vengono applicate a elementi singoli

Fino a questo punto, abbiamo visto proprietà che puoi applicare al contenitore.

I singoli elementi possono avere una certa indipendenza e flessibilità, e ne puoi alterare l'aspetto usando queste proprietà:

  • order
  • align-self
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex

Vediamole in dettaglio.

Spostare un elemento prima o dopo di un altro usando order

Gli elementi sono ordinati in base all'ordine assegnato. Di default ogni elemento ha order 0 e la comparsa nell'HTML determina l'ordine finale.

Puoi sovrascrivere questa proprietà usando order su ogni singolo elemento. Si tratta di una proprietà che imposti sull'elemento, non sul contenitore. Puoi far apparire un elemento prima degli altri impostando un valore negativo.

B1sZQ2N0Faporf-B6QSoT9qlksFM0ul6Ova2

Allineamento verticale usando align-self

Per un elemento è possibile sovrascrivere l'impostazione align-items del contenitore, usando align-self, che ha gli stessi 5 possibili valori di align-items:

  • flex-start: allinea in cima al contenitore.
  • flex-end: allinea in fondo al contenitore.
  • center: allinea al centro del contenitore verticalmente.
  • baseline: allinea alla linea di base del contenitore.
  • stretch: gli elementi sono estesi fino a riempire il contenitore.
Vgk2OOS4KMX-ABecwTGMZGxu5HNOUsSCguNv

Espandere o rimpicciolire un elemento se necessario

flex-grow

Il valore predefinito per ogni elemento è 0.

Se tutti gli elementi sono definiti come 1 e un elemento è definito come 2, l'elemento più grande occuperà la spazio di due elementi "1".

flex-shrink

Il valore predefinito per ogni elemento è 1.

Se tutti gli elementi sono definiti come 1 e uno è definito come 3, l'elemento più grande rimpicciolirà di tre volte rispetto agli altri. Quando è disponibile meno spazio, occuperà 3 volte meno spazio.

flex-basis

Se impostato su auto, ridimensiona un elemento secondo la sua larghezza o altezza, e aggiunge spazio extra in base alla proprietà flex-grow.

Se impostata a 0, non aggiunge alcuno spazio extra per gli elementi nel calcolo del layout.

Se specifichi un valore numerico in pixel, verrà usato come valore di lunghezza (larghezza o altezza a seconda che si tratti di un elemento riga o colonna).

flex

Questa proprietà combina le 3 proprietà precedenti:

  • flex-grow
  • flex-shrink
  • flex-basis

e offre una sintassi accorciata: flex: 0 1 auto

TABELLE

Nel passato, si è abusato dell'utilizzo delle tabelle in CSS, dato che erano l'unico modo per creare dei layout fantasiosi.

Oggi con Grid e Flexbox possiamo restituire alle tabelle la loro funzione originaria.

Iniziamo dall'HTML. Questa è una tabella base:

<table>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Age</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Flavio</th>
      <td>36</td>
    </tr>
    <tr>
      <th scope="row">Roger</th>
      <td>7</td>
    </tr>
  </tbody>
</table>

Di default non è molto accattivante. Il browser fornisce degli stili standard ed ecco tutto:

cSv50H4eDfA17z4XhwXhlwgDCzfrtAkth840

Naturalmente, possiamo usare il CSS per definire lo stile di tutti gli elementi nella tabella.

Partiamo dal bordo. Un buon bordo può fare molto.

Possiamo applicarlo all'elemento table e anche agli elementi interni, come th e td:

table, th, td {
  border: 1px solid #333;
}

Se lo abbiniamo a del margine, otteniamo un buon risultato:

77EZWjHTyPL1-2BHjB6PtNKGxoefvaH8Ou0N

Una cosa comune con le tabelle è la possibilità di aggiungere un colore a una riga e un colore diverso alla successiva. Questo è possibile usando il selettore :nth-child(odd) o :nth-child(even):

tbody tr:nth-child(odd) {
  background-color: #af47ff;
}

Il risultato è:

bgYEzQ0jzePRY8Z1QsjS8Wr33gzw8Hm2R0-o

Se aggiungi border-collapse: collapse; all'elemento table, tutti i bordi collassano in un bordo unico:

YBEKBLgWtAy6VbpdnQCbpIzfWJYKvGPesyGA

CENTRATURA

Centrare le cose in CSS è un'attività a seconda che si tratti di farlo orizzontalmente o verticalmente.

Qui spiegherò gli scenari più comuni e come risolverli. Se Flexbox fornisce una nuova soluzione, ignoro la vecchia tecnica perché abbiamo bisogno di andare avanti e Flexbox viene supportato dai browser da anni, incluso IE10.

Centrare orizzontalmente

Testo

Il testo è molto semplice da centrare orizzontalmente usando la proprietà text-align impostata su center:

p {
  text-align: center;
}

Blocchi

Il modo moderno per centrare qualsiasi cosa che non sia testo è usare Flexbox:

#mysection {
  display: flex;
  justify-content: center;
}

ogni elemento all'interno di #mysection sarà centrato orizzontalmente.

poUby5NpYUt0D8ADmTgP6wWXhjj2PMjWuK4p

Ecco l'approccio alternativo se non vuoi usare Flexbox.

Qualsiasi cosa che non è testo può essere centrata applicando un margine automatico a sinistra e a destra, e impostando la larghezza dell'elemento:

section {
  margin: 0 auto;
  width: 50%;
}

margin: 0 auto; è una scorciatoia per:

section {
  margin-top: 0;
  margin-bottom: 0;
  margin-left: auto;
  margin-right: auto;
}

Ricorda di impostare l'elemento su display: block se si tratta di un elemento inline.

Centrare verticalmente

Tradizionalmente, questa è stata sempre un'attività difficile. Flexbox adesso ci offre un ottimo modo per farlo con estrema semplicità:

#mysection {
  display: flex;
  align-items: center;
}

ogni elemento all'interno di #mysection sarà centrato verticalmente.

XOIWKiWU2zPe3VNje1LpiaHur6lJu4db8Cyp

Centrare sia orizzontalmente che verticalmente

Le tecniche Flexbox per centrare verticalmente e orizzontalmente possono essere combinate per centrare completamente un elemento nella pagina.

#mysection {
  display: flex;
  align-items: center;
  justify-content: center;
}
OtQEQ-F5AsSU0b49Oo5cGwoyLafxN05qmoLQ

Si può fare la stessa cosa usando CSS Grid:

body {
  display: grid;
  place-items: center;
  height: 100vh;
}

LISTE

Le liste sono delle parti molto importanti di molte pagine web.

Il CSS può definirne lo stile usando svariate proprietà.

list-style-type viene usata per impostare un indicatore predefinito da usare nella lista:

li {
  list-style-type: square;
}

Abbiamo tanti valori possibili, che puoi vedere qui https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type con esempi del loro aspetto. Alcuni dei più comuni sono disc, circle, square e none.

list-style-image viene usato per definire un indicatore personalizzato quando uno predefinito non è appropriato:

li {
  list-style-image: url(list-image.png);
}

list-style-position ti consente di aggiungere l'indicatore fuori (outside, valore predefinito) o all'interno (inside) del contenuto della lista, nel flusso della pagina anziché fuori da esso

li {
  list-style-position: inside;
}

La proprietà scorciatoia list-style ci permette di specificare tutte queste proprietà sulla stessa riga:

li {
  list-style: url(list-image.png) inside;
}

MEDIA QUERY E DESIGN RESPONSIVO

In questa sezione, inizieremo introducendo le tipologie (media type) e i descrittori di media feature, e poi passeremo alle media query.

Tipologie

Usate nelle media query e nelle dichiarazioni @import, le tipologie ci consentono di determinare su quale dispositivo viene caricato un file CSS o una porzione di CSS.

Abbiamo le seguenti tipologie

  • all vuol dire su tutti i dispositivi
  • print è usato nella stampa
  • screen è usato quando la pagina viene presentata su uno schermo
  • speech è usato per i lettori di schermo

screen è quella predefinita.

Nel passato ne avevamo altre, ma sono per lo più obsolete dato che si sono dimostrate inefficaci per determinare le esigenze di un dispositivo.

Possiamo usarle nelle dichiarazioni @import in questo modo:

@import url(myfile.css) screen;
@import url(myfile-print.css) print;

Possiamo caricare un file CSS su più tipologie di dispositivo separandole con una virgola:

@import url(myfile.css) screen, print;

Funzionano anche nei tag link in HTML:

<link rel="stylesheet" type="text/css" href="myfile.css" media="screen" />
<link rel="stylesheet" type="text/css" href="another.css" media="screen, print" />

Non siamo limitati all'uso di queste tipologie per l'attributo media in una dichiarazione @import. C'è altro.

Descrittori di media feature

Prima di tutto, introduciamo i descrittori di media feature. Si tratta di parole chiave aggiuntive che si possono aggiungere all'attributo media di un link o di una dichiarazione @import, per esprimere più condizioni sul caricamento del CSS.

Ecco la loro lista:

  • width
  • height
  • device-width
  • device-height
  • aspect-ratio
  • device-aspect-ratio
  • color
  • color-index
  • monochrome
  • resolution
  • orientation
  • scan
  • grid

Ognuno ha il corrispondente min- e max-, ad esempio:

  • min-width, max-width
  • min-device-width, max-device-width

e così via.

Alcuni accettano un valore di lunghezza che può essere espresso in px o rem o qualsiasi unità di lunghezza. È il caso width, height, device-width, device-height.

Ad esempio:

@import url(myfile.css) screen and (max-width: 800px);

Nota che ogni blocco che fa uso di una media feature viene racchiuso tra parentesi.

Alcuni accettano un valore fisso. orientation, usato per rilevare l'orientazione del dispositivo, accetta portrait o landscape.

Esempio:

<link rel="stylesheet" type="text/css" href="myfile.css" media="screen and (orientation: portrait)" />

scan, usato per determinare il tipo di schermo, accetta progressive (per i display moderni) o interlace (per i più vecchi dispositivi CRT).

Altri vogliono un intero.

Come color, che controlla in numero di bit per componente di colore usati nel dispositivo. Si tratta di un livello molto basso, ma devi soltanto sapere che è lì per essere utilizzato (come grid, color-index, monochrome).

aspect-ratio e device-aspect-ratio accettano un valore che rappresenta il rapporto tra larghezza e altezza del viewport, espresso come frazione.

Esempio:

@import url(myfile.css) screen and (aspect-ratio: 4/3);

resolution rappresenta la densità di pixel, espressa in un unità di misura di risoluzione (resolution data type) come dpi.

Esempio:

@import url(myfile.css) screen and (min-resolution: 100dpi);

Operatori logici

Possiamo combinare delle regole usando and:

<link rel="stylesheet" type="text/css" href="myfile.css" media="screen and (max-width: 800px)" />

Possiamo eseguire un operazione logica di tipo "or" usando le virgole, che combinano più media query:

@import url(myfile.css) screen, print;

Possiamo usare not per negare una media query:

@import url(myfile.css) not screen;
Importante: not può essere usato solo per negare un'intera media query, quindi va posizionato al suo inizio (o dopo una virgola).

Media query

Tutti le regole qui sopra che abbiamo visto applicate a un @import o nel tag HTML link possono essere applicate anche all'interno del CSS.

Devi racchiuderle in una struttura del tipo @media () {}.

Esempio:

@media screen and (max-width: 800px) {
  /* inserisci del CSS */
}

Questa è la base del design responsivo.

Le media query possono essere piuttosto complesse. Questo esempio applica il CSS solo a uno schermo, se la larghezza è compresa tra 600 e 800 pixel e se l'orientazione è landscape:

@media screen and (max-width: 800px) and (min-width: 600px) and (orientation: landscape) {
  /* enter some CSS */
}

FEATURE QUERY

Le feature query costituiscono una recente e relativamente sconosciuta abilità del CSS, anche se ben supportata.

Possiamo usarle per controllare se una feature è supportata dal browser con la parola chiave @supports.

Ritengo che sia particolarmente utile, almeno al momento della scrittura di questo manuale, per controllare il supporto di CSS Grid, che può essere verificato usando:

@supports (display: grid) {
  /* applica questo CSS */
}

Possiamo controllare se il browser supporta il valore grid per la proprietà display.

Possiamo usare @supports per qualsiasi proprietà CSS, per verificare ogni valore.

Possiamo anche usare gli operatori logici and, or e not per costruire feature query complesse:

@supports (display: grid) and (display: flex) {
  /* applica questo CSS */
}

FILTRI

I filtri ci permettono di eseguire delle operazioni sugli elementi.

Cose che normalmente faresti con Photoshop o altri software per l'editing di immagini, come cambiare l'opacità, la luminosità e altro.

Puoi usare la proprietà filter. Qui c'è un esempio in cui è applicata a un'immagine, ma questa proprietà può essere applicata a qualsiasi elemento:

img {
  filter: <qualcosa>;
}

Puoi usare diversi valori qui:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • sepia()
  • saturate()
  • url()

Nota le parentesi dopo ogni opzione, in quanto richiedono tutte un parametro.

Ad esempio:

img {
  filter: opacity(0.5);
}

vuol dire che l'immagine sarà trasparente al 50%, perché opacity() accetta un valore tra 0 e 1 o una percentuale.

Puoi anche applicare più filtri insieme:

img {
  filter: opacity(0.5) blur(2px);
}

Vediamo ogni filtro in dettaglio.

blur()

Sfoca il contenuto di un elemento. Occorre passare un valore espresso in px, em o rem che viene usato per determinare il raggio di sfocatura.

Esempio:

img {
  filter: blur(4px);
}

opacity()

opacity() accetta un valore tra 0 e 1, o una percentuale, e su questa base determina la trasparenza dell'immagine.

0 o 0% vuol dire totalmente trasparente. 1, 100% o maggiore vuol dire totalmente visibile.

Esempio:

img {
  filter: opacity(0.5);
}

Il CSS ha anche una proprietà opacity. filter però può essere accelerato dall'hardware, a seconda dell'implementazione, quindi dovrebbe essere il metodo preferito.

drop-shadow()

drop-shadow() mostra un'ombra dietro all'elemento, che segue il canale alfa. Ciò vuol dire che se hai un'immagine trasparente, ottieni un'ombra applicata alla forma dell'immagine, e non al riquadro dell'immagine. Se l'immagine non ha un canale alfa, l'ombra viene applicata all'intero riquadro.

Accetta un minimo di 2 parametri, fino a 5:

  • offset-x imposta lo sfasamento orizzontale. Può essere negativo.
  • offset-y imposta lo sfasamento verticale. Può essere negativo.
  • blur-radius, opzionale, imposta il livello di sfocatura per l'ombra. Di default è 0 (nessuna sfocatura).
  • spread-radius, opzionale, imposta il livello di diffusione. Espresso in px, rem o em
  • color, opzionale, imposta il colore dell'ombra.

Puoi impostare il colore senza definire il livello di diffusione o di sfocatura. Il CSS comprende che il valore è un colore e non una lunghezza.

Esempio:

img {
  filter: drop-shadow(10px 10px 5px orange);
}

img {
  filter: drop-shadow(10px 10px orange);
}

img {
  filter: drop-shadow(10px 10px 5px 5px #333);
}

grayscale()

Rende l'elemento in scala di grigi.

Puoi passare un valore da 0 a 1, o dallo 0% al 100%, dove 1 e 100% significano completamente grigio, e 0 o 0% significano che l'immagine non è alterata e resta del colore originario.

Esempio:

img {
  filter: grayscale(50%);
}

sepia()

Rende l'elemento di color seppia.

Puoi passare un valore da 0 a 1, o dallo 0% al 100%, dove 1 e 100% significano completamente seppia, e 0 o 0% significano che l'immagine non è alterata e resta del colore originario.

Esempio:

img {
  filter: sepia(50%);
}

invert()

Inverte i colori di un elemento. Invertire un colore significa usare il colore opposto nella ruota dei colori HSL. Se non hai idea di ciò che vuol dire, prova a cercare "ruota dei colori" su Google. Ad esempio, l'opposto del giallo è il blu, l'opposto del rosso è il ciano. Ogni colore ha un opposto.

Puoi passare un numero da 0 a 1 oppure dallo 0% al 100%, che determina la quantità dell'inversione. 1 o 100% vuol dire inversione completa, 0 o 0% vuol dire nessuna inversione.

0.5 o 50% presenteranno un colore grigio al 50%, perché si va a finire nel mezzo della ruota.

Esempio:

img {
  filter: invert(50%);
}

hue-rotate()

La ruota dei colori HSL è rappresentata in gradi. Usando hue-rotate() puoi ruotare il colore usando una rotazione positiva o negativa.

La funzione accetta un valore in gradi (deg).

Esempio:

img {
  filter: hue-rotate(90deg);
}

brightness()

Altera la luminosità di un elemento.

0 o 0% restituisce un elemento totalmente nero. 1 o 100% dà un'immagine invariata.

Valori più alti di 1 o 100% rendono l'immagine più luminosa fino a ottenere un elemento totalmente bianco.

Esempio:

img {
  filter: brightness(50%);
}

contrast()

Altera il contrasto di un elemento.

0 o 0% restituiscono un elemento totalmente grigio. 1 o 100% danno un'immagine invariata.

Valori più alti di 1 o 100% danno più contrasto.

Esempio:

img {
  filter: contrast(150%);
}

saturate()

Altera la saturazione di un elemento.

0 o 0% danno un elemento completamente in scala di grigi (con meno saturazione). 1 o 100% danno un'immagine inalterata.

Valori più alti di 1 o 100% danno più saturazione.

Esempio:

img {
  filter: saturate();
}

url()

Questo filtro permette di applicare un filtro definito in un file SVG. Occorre fare riferimento alla posizione del file SVG.

Esempio:

img {
  filter: url(filter.svg);
}

I filtri SVG vanno al di fuori dello scopo di questo manuale, ma puoi trovare più informazioni a riguardo in questo post su Smashing Magazine: https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/ (risorsa in lingua originale inglese).

TRASFORMAZIONI

Le trasformazioni ti consentono di traslare, ruotare, scalare e inclinare elementi nello spazio 2D e 3D. Sono una funzionalità fantastica del CSS, specialmente quando combinati con le animazioni.

Trasformazioni 2D

La proprietà transform accetta queste funzioni:

  • translate() per spostare elementi
  • rotate() per ruotare elementi
  • scale() per scalare elementi in dimensione
  • skew() per distorcere o inclinare un elemento
  • matrix() un modo per eseguire ognuna di queste operazioni usando una matrice di 6 elementi, una sintassi meno user-friendly ma meno verbose

Esistono anche le funzioni specifiche per gli assi:

  • translateX() per spostare gli elementi attorno all'asse X
  • translateY() per spostare gli elementi attorno all'asse Y
  • scaleX() per scalare le dimensioni di un elemento sull'asse X
  • scaleY() per scalare le dimensioni di un elemento sull'asse Y
  • skewX() per distorcere o inclinare un elemento sull'asse X
  • skewY() per distorcere o inclinare un elemento sull'asse Y

Ecco un esempio di una trasformazione in cui raddoppia la larghezza dell'elemento .box mentre la sua altezza si dimezza:

.box {
    transform: scale(2, 0.5);
}

transform-origin ci permette di impostare l'origine (le coordinate (0, 0)) per la trasformazione, cambiando il centro di rotazione.

Combinare più trasformazioni

Puoi combinare più trasformazioni separando ogni funzione con uno spazio.

Ad esempio:

transform: rotateY(20deg) scaleX(3) translateY(100px);

Trasformazioni 3D

Possiamo fare un altro passo e spostare i nostri elementi in uno spazio 3D invece che 2D. Con il 3D, stiamo aggiungendo un altro asse, Z, che aggiunge profondità alla visuale.

Usando la proprietà perspective puoi specificare quanto lontano dall'utente si trova l'oggetto 3D.

Esempio:

.3Delement {
  perspective: 100px;
}

perspective-origin determina l'aspetto della posizione dell'osservatore, il modo in cui guardiamo agli assi X e Y.

Ora possiamo usare alcune funzioni aggiuntive per controllare l'asse Z e che si aggiungono alle trasformazioni sugli assi X e Y:

  • translateZ()
  • rotateZ()
  • scaleZ()

e le corrispondenti scorciatoie translate3d(), rotate3d() e scale3d() per usare le funzioni translateX(), translateY() e translateZ() e via dicendo.

Le trasformazioni 3D sono un po' avanzate per questo manuale, ma sono un fantastico argomento che puoi esplorare per conto tuo.

TRANSIZIONI

Le transizioni CSS sono il modo più semplice per creare un'animazione in CSS.

In una transizione, si cambia il valore di una proprietà, dicendo al CSS di cambiarla lentamente in accordo con alcuni parametri, fino a uno stato finale.

Le transizioni CSS sono definite da queste proprietà:

Proprietà Descrizione
transition-property La proprietà CSS che dovrebbe variare.
transition-duration La durata della transizione.
transition-timing-function La funzione temporale usata dall'animazione (valori comuni: linear, ease). Valore predefinito: ease.
transition-delay Numero opzionale di secondi da attendere prima che inizi l'animazione.

La proprietà transition è una comoda scorciatoia:

.container {
  transition: property
              duration
              timing-function
              delay;
}

Esempi di transizioni CSS

Questo codice implementa una transizione CSS:

.one,
.three {
  background: rgba(142, 92, 205, .75);
  transition: background 1s ease-in;
}

.two,
.four {
  background: rgba(236, 252, 100, .75);
}

.circle:hover {
  background: rgba(142, 92, 205, .25); /* lighter */
}

Vedi l'esempio su Glitch https://flavio-css-transitions-example.glitch.me

Quando passi con il cursore sugli elementi .one e .three, i cerchi viola, c'è una transizione che attenua il cambio di sfondo, mentre i cerchi gialli non lo fanno, in quanto non posseggono una proprietà transition definita.

Valori di transition-timing-function

transition-timing-function ti permette di specificare la curva di accelerazione della transizione.

Ecco alcuni semplici valori che puoi usare:

  • linear
  • ease
  • ease-in
  • ease-out
  • ease-in-out

Questo Glitch ne mostra il funzionamento pratico.

Puoi creare una funzione completamente personalizzata usando le curve di Bezier cubiche. Si tratta di un concetto piuttosto avanzato, ma in pratica, ognuna delle funzioni viste sopra è costruita usando delle curve di Bezier.

Transizioni CSS negli strumenti per sviluppatori del browser

Gli strumenti per sviluppatori del browser offrono un fantastico modo di visualizzare le transizioni.

Questo è Chrome:

l6svCI9t6bLTsuniRuxjgwOnD9i1YSseno-f

Questo è Firefox:

JYAWK9J6xuzeP2WVytUt8k64RUUCHl3UJmXC

Da questi pannelli puoi modificare la transizione in tempo reale e sperimentare sulla pagina direttamente senza ricaricare il tuo codice.

Quali proprietà puoi animare con le transizioni CSS

Un sacco! Sono le stesse che puoi animare usando le animazioni CSS.

Ecco la lista completa:

  • background
  • background-color
  • background-position
  • background-size
  • border
  • border-color
  • border-width
  • border-bottom
  • border-bottom-color
  • border-bottom-left-radius
  • border-bottom-right-radius
  • border-bottom-width
  • border-left
  • border-left-color
  • border-left-width
  • border-radius
  • border-right
  • border-right-color
  • border-right-width
  • border-spacing
  • border-top
  • border-top-color
  • border-top-left-radius
  • border-top-right-radius
  • border-top-width
  • bottom
  • box-shadow
  • caret-color
  • clip
  • color
  • column-count
  • column-gap
  • column-rule
  • column-rule-color
  • column-rule-width
  • column-width
  • columns
  • content
  • filter
  • flex
  • flex-basis
  • flex-grow
  • flex-shrink
  • font
  • font-size
  • font-size-adjust
  • font-stretch
  • font-weight
  • grid-area
  • grid-auto-columns
  • grid-auto-flow
  • grid-auto-rows
  • grid-column-end
  • grid-column-gap
  • grid-column-start
  • grid-column
  • grid-gap
  • grid-row-end
  • grid-row-gap
  • grid-row-start
  • grid-row
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows
  • grid-template
  • grid
  • height
  • left
  • letter-spacing
  • line-height
  • margin
  • margin-bottom
  • margin-left
  • margin-right
  • margin-top
  • max-height
  • max-width
  • min-height
  • min-width
  • opacity
  • order
  • outline
  • outline-color
  • outline-offset
  • outline-width
  • padding
  • padding-bottom
  • padding-left
  • padding-right
  • padding-top
  • perspective
  • perspective-origin
  • quotes
  • right
  • tab-size
  • text-decoration
  • text-decoration-color
  • text-indent
  • text-shadow
  • top
  • transform.
  • vertical-align
  • visibility
  • width
  • word-spacing
  • z-index

ANIMAZIONI

Le animazioni CSS sono un fantastico modo per creare animazioni visuali, non limitate a singoli movimenti come le transizioni CSS, ma ben più articolate.

Un'animazione viene applicata a un elemento usando la proprietà animation.

.container {
  animation: spin 10s linear infinite;
}

spin è il nome dell'animazione, che dobbiamo definire separatamente. Abbiamo anche detto al CSS di far durare l'animazione 10 secondi, di eseguirla in modo lineare (nessuna accelerazione o variazione di velocità) e di ripeterla all'infinito.

Occorre definire come funziona l'animazione usando keyframes. Ecco un esempio di un'animazione che ruota un elemento:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

All'interno della definizione @keyframes puoi avere tutti i punti intermedi che desideri.

In questo caso, ordiniamo al CSS di far ruotare l'asse Z alla proprietà transform da 0 a 360 gradi, completando un giro.

Puoi usare qualsiasi trasformazione CSS qui.

Nota che questo non implica nulla riguardo all'intervallo temporale che dovrebbe occupare l'animazione, che è definito quando la usiamo, attraverso animation.

Esempio di animazione CSS

Voglio disegnare quattro cerchi, tutti che cominciano da un punto in comune e distanti 90 gradi l'uno dall'altro.

<div class="container">
  <div class="circle one"></div>
  <div class="circle two"></div>
  <div class="circle three"></div>
  <div class="circle four"></div>
</div>

body {
  display: grid;
  place-items: center;
  height: 100vh;
}

.circle {
  border-radius: 50%;
  left: calc(50% - 6.25em);
  top: calc(50% - 12.5em);
  transform-origin: 50% 12.5em;
  width: 12.5em;
  height: 12.5em;
  position: absolute;
  box-shadow: 0 1em 2em rgba(0, 0, 0, .5);
}

.one,
.three {
  background: rgba(142, 92, 205, .75);
}

.two,
.four {
  background: rgba(236, 252, 100, .75);
}

.one {
  transform: rotateZ(0);
}

.two {
  transform: rotateZ(90deg);
}

.three {
  transform: rotateZ(180deg);
}

.four {
  transform: rotateZ(-90deg);
}

Vedi questo Glitch: https://flavio-css-circles.glitch.me

Ruotiamo questa struttura (tutti i cerchi insieme). Per farlo applichiamo un'animazione sul contenitore e la definiamo come una rotazione di 360 gradi:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

.container {
  animation: spin 10s linear infinite;
}

Guardala su https://flavio-css-animations-tutorial.glitch.me

Puoi aggiungere altri keyframes per ottenere animazioni più divertenti:

@keyframes spin {
  0% {
    transform: rotateZ(0);
  }
  25% {
    transform: rotateZ(30deg);
  }
  50% {
    transform: rotateZ(270deg);
  }
  75% {
    transform: rotateZ(180deg);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

Guarda l'esempio su https://flavio-css-animations-four-steps.glitch.me

Le proprietà delle animazioni CSS

Le animazioni CSS offrono molti parametri diversi che puoi modificare:

Proprietà Descrizione
animation-name Il nome dell'animazione, fa riferimento a un'animazione creata con @keyframes.
animation-duration Quanto dovrebbe durare l'animazione in secondi.
animation-timing-function La funzione temporale usata dall'animazione (valori comuni: linear, ease). Valore predefinito: ease.
animation-delay Numero opzionale di secondi da aspettare prima che parta l'animazione.
animation-iteration-count Quante volte dovrebbe essere eseguita l'animazione. Accetta un numero o infinite. Valore predefinito: 1.
animation-direction La direzione dell'animazione. Può essere normal, reverse, alternate o alternate-reverse. Con gli ultimi 2, si alterna andando avanti e indietro.
animation-fill-mode Definisce lo stile di un elemento quando l'animazione finisce, al termine del conto delle iterazioni. none o backwards tornano allo stile del primo keyframe. forwards e both usano lo stile impostato nell'ultimo keyframe.
animation-play-state Se impostato su paused mette in pausa l'animazione. Il valore predefinito è running.

La proprietà animation è la scorciatoia per tutte queste proprietà, in quest'ordine:

.container {
  animation: name
             duration
             timing-function
             delay
             iteration-count
             direction
             fill-mode
             play-state;
}

Questo è l'esempio che abbiamo usato sopra:

.container {
  animation: spin 10s linear infinite;
}

Eventi JavaScript per le animazioni CSS

Usando JavaScript puoi avvertire i seguenti eventi:

  • animationstart
  • animationend
  • animationiteration

Stai attento con animationstart, perché se l'animazione inizia al caricamento della pagina, il codice JavaScript viene eseguito sempre dopo che il CSS viene processato, quindi l'animazione è già iniziata e non puoi intercettare l'evento.

const container = document.querySelector('.container')

container.addEventListener('animationstart', (e) => {
  //do something
}, false)

container.addEventListener('animationend', (e) => {
  //do something
}, false)

container.addEventListener('animationiteration', (e) => {
  //do something
}, false)

Quali proprietà puoi animare usando le animazioni CSS

Un sacco! Sono le stesse che puoi animare usando le transizioni CSS.

Ecco la lista completa:

  • background
  • background-color
  • background-position
  • background-size
  • border
  • border-color
  • border-width
  • border-bottom
  • border-bottom-color
  • border-bottom-left-radius
  • border-bottom-right-radius
  • border-bottom-width
  • border-left
  • border-left-color
  • border-left-width
  • border-radius
  • border-right
  • border-right-color
  • border-right-width
  • border-spacing
  • border-top
  • border-top-color
  • border-top-left-radius
  • border-top-right-radius
  • border-top-width
  • bottom
  • box-shadow
  • caret-color
  • clip
  • color
  • column-count
  • column-gap
  • column-rule
  • column-rule-color
  • column-rule-width
  • column-width
  • columns
  • content
  • filter
  • flex
  • flex-basis
  • flex-grow
  • flex-shrink
  • font
  • font-size
  • font-size-adjust
  • font-stretch
  • font-weight
  • grid-area
  • grid-auto-columns
  • grid-auto-flow
  • grid-auto-rows
  • grid-column-end
  • grid-column-gap
  • grid-column-start
  • grid-column
  • grid-gap
  • grid-row-end
  • grid-row-gap
  • grid-row-start
  • grid-row
  • grid-template-areas
  • grid-template-columns
  • grid-template-rows
  • grid-template
  • grid
  • height
  • left
  • letter-spacing
  • line-height
  • margin
  • margin-bottom
  • margin-left
  • margin-right
  • margin-top
  • max-height
  • max-width
  • min-height
  • min-width
  • opacity
  • order
  • outline
  • outline-color
  • outline-offset
  • outline-width
  • padding
  • padding-bottom
  • padding-left
  • padding-right
  • padding-top
  • perspective
  • perspective-origin
  • quotes
  • right
  • tab-size
  • text-decoration
  • text-decoration-color
  • text-indent
  • text-shadow
  • top
  • transform.
  • vertical-align
  • visibility
  • width
  • word-spacing
  • z-index

NORMALIZZARE IL CSS

Il foglio di stile predefinito del browser è un insieme di regole che i browser applicano per dare un minimo di stile agli elementi.

Il più delle volte questi stili sono molto utili.

Dato che ogni browser ha il proprio set di regole, è comune trovare un punto d'incontro.

Piuttosto che rimuovere tutti gli stili predefiniti, come con l'approccio reset CSS, il processo di normalizzazione rimuove le incongruenze del browser, mantenendo un insieme di regole di base su cui puoi fare affidamento.

Normalize.css http://necolas.github.io/normalize.css è la soluzione più usata per questo problema.

Devi caricare il file di normalizzazione del CSS prima di qualsiasi altro CSS.

GESTIONE DEGLI ERRORI

Il CSS è resiliente. Quando trova un errore, non agisce come JavaScript, che fa i bagagli e scompare del tutto, terminando l'esecuzione degli script dopo aver trovato l'errore.

Il CSS prova a fare quello che vuole.

Se una riga contiene un errore, la salta e passa alla riga successiva priva di errori.

Se dimentichi il punto e virgola in una riga:

p {
  font-size: 20px
  color: black;
  border: 1px solid black;
}

la riga con l'errore E la successiva non saranno applicate, ma la terza regola sarà applicata con successo alla pagina. In sostanza, analizza tutto finché non trova un punto e virgola, ma quando lo raggiunge, la regola è font-size: 20px color: black;, che non è valida, quindi la salta.

A volte è complicato capire che c'è un errore da qualche parte, e dove si trova, dato che il browser non lo comunica.

Ecco perché esistono strumenti come CSS Lint.

PREFISSI VENDOR

I prefissi vendor sono un modo con cui i browser danno accesso alle nuove feature considerate non ancora stabili agli sviluppatori CSS.

Prima di proseguire, tieni a mente che questo approccio sta perdendo popolarità. Le persone adesso preferiscono usare i flag sperimentali, che devono essere abilitati esplicitamente nel browser dell'utente.

Perché? Perché gli sviluppatori, invece di considerare i prefissi vendor un modo di avere un'anteprima delle feature, a volte li mandano in produzione – il che è considerato dannoso dal gruppo di lavoro CSS.

Principalmente perché una volta che hai aggiunto un flag e gli sviluppatori iniziano a usarlo in produzione, i browser sono in una brutta posizione se si rendono conto che qualcosa deve essere cambiato. Con i flag, non puoi mandare una feature in produzione a meno che non spingi tutti i tuoi utenti ad abilitare il flag nel proprio browser (sto scherzando, non provarci).

Detto ciò, vediamo cosa sono i prefissi vendor.

Li ricordo, in particolare, per aver lavorato con le transizioni CSS in passato. Invece di usare semplicemente la proprietà transition, bisognava scrivere questo:

.myClass {
    -webkit-transition: all 1s linear;
    -moz-transition: all 1s linear;
    -ms-transition: all 1s linear;
    -o-transition: all 1s linear;
    transition: all 1s linear;
}

Adesso si usa solo:

.myClass {
    transition: all 1s linear;
}

dato che la proprietà è ben supportata da tutti i browser moderni.

I prefissi usati sono:

  • -webkit- (Chrome, Safari, iOS Safari / iOS WebView, Android)
  • -moz- (Safari)
  • -ms- (Edge, Internet Explorer)
  • -o- (Opera, Opera Mini)

Dato che Opera è basato su Chromium e Edge lo sarà presto, -o- e -ms- saranno presto fuori moda. Ma come abbiamo detto, i prefissi vendor stessi stanno andando fuori moda.

Scrivere i prefissi è difficile, soprattutto per l'incertezza. Ti serve davvero un prefisso per una certa proprietà? Diverse risorse online non sono aggiornate, rendendo ancora più difficile agire nel modo corretto. Progetti come Autoprefixer possono automatizzare il processo nella sua interezza senza aver bisogno di cercare se il prefisso è ancora necessario, o se la feature è stabile e il prefisso dovrebbe essere eliminato. Utilizza i dati da caniuse.com, un ottimo sito di riferimento per tutte le cose relative al supporto browser.

Se utilizzi React o Vue, progetti come create-react-app e Vue CLI, due modi comuni per iniziare a costruire un'applicazione, hanno autoprefixer pronto all'uso, in modo che non devi neanche preoccupartene.

CSS PER LA STAMPA

Anche stiamo sempre di più sui nostri schermi, la stampa è ancora comune.

Persino con i post dei blog. Ricordo che nel 2009 incontrai una persona che mi disse di aver fatto stampare al suo assistente personale ogni post del mio blog che ho pubblicato (sì, l'ho fissato perplesso per un po'). Decisamente inaspettato.

L'utilizzo principale che faccio della stampa si limita a stampare un PDF. Potrei creare qualcosa sul browser e renderlo disponibile in PDF.

I browser lo rendono molto semplice, con il "Salva" predefinito di Chrome quando provi a stampare un documento e non c'è una stampante disponibile, e l'apposito pulsante di Safari nella barra dei menu:

bgA5gq1sJ4vzRx7inVg4skJLVgDggyhDjhmF

Stampare il CSS

Alcune cose comuni che potresti desiderare di fare per la stampa sono nascondere delle parti del documento, come il piè di pagina, qualcosa nell'intestazione o nella barra laterale.

Magari vuoi usare un carattere diverso per la stampa, che è assolutamente legittimo.

Se hai un CSS grande per la stampa, faresti meglio a usare un file separato. I browser lo scaricheranno solo durante la stampa:

<link rel="stylesheet"
      src="print.css"
      type="text/css"
      media="print" />

@media print CSS

Un'alternativa all'approccio precedente è una media query. Qualsiasi cosa aggiungi all'interno di questo blocco:

@media print {
  /* ... */
}

sarà applicata soltanto ai documenti stampati.

L'HTML è fantastico grazie ai link. Si chiama HyperText per una buona ragione. Con la stampa potresti perdere un sacco di informazioni, a seconda del contenuto.

Il CSS offre un ottimo modo di risolvere questo problema modificando il contenuto, cioè aggiungendo il link dopo il testo del tag <a>, usando:

@media print {
    a[href*='//']:after {
        content:" (" attr(href) ") ";
        color: $primary;
    }
}

Seleziono a[href*='//'] per farlo soltanto per i link esterni. Potrebbero esserci link a scopo di navigazione e indicizzazione interna, che sarebbero inutili nella maggior parte dei casi. Se vuoi che siano stampati anche i link interni, puoi usare:

@media print {
    a:after {
        content:" (" attr(href) ") ";
        color: $primary;
    }
}

Margini

Puoi aggiungere i margini a ogni singola pagina. cm o in sono buone unità di misura per la carta stampata.

@page {
    margin-top: 2cm;
    margin-bottom: 2cm;
    margin-left: 2cm;
    margin-right: 2cm;
}

@page può essere usato anche per selezionare la prima pagina, usando @page :first, o soltanto le pagine a sinistra o a destra con @page :left e @page: right.

Interruzioni di pagina

Potresti voler aggiungere un'interruzione di pagine dopo o prima di certi elementi. Usa page-break-after e page-break-before:

.book-date {
    page-break-after: always;
}

.post-content {
    page-break-before: always;
}

Queste proprietà accettano un'ampia gamma di valori.

Evitare di spezzare le immagini a metà

Ne ho avuto esperienza con Firefox: le immagini sono tagliate nel mezzo di default, continuando nella pagina successiva. Potrebbe accadere anche al testo.

Utilizza:

p {
  page-break-inside: avoid;
}

e racchiudi le immagini in un tag p. Selezionando direttamente img non ha funzionato nei test che ho fatto.

Tutto ciò si applica anche ad altri contenuti, non solo a immagini. Se noti che qualcosa viene tagliato quando non vuoi, usa questa proprietà.

Debug dell'anteprima di stampa

Gli strumenti per sviluppatori di Chrome offrono dei modi per emulare il layout di stampa:

-uiIs0O58DxJGuPKuMjjzg356Nq2On7GH7QI

Una volta aperto il pannello rendering, cambia l'emulazione in print:

XO5KBdEIBUtWLlIXwISJMN3GaehM9Gfd22K7

CONCLUSIONE

Spero che questo manuale ti abbia aiutato a metterti in pari con il CSS e ad avere una panoramica delle funzionalità principali che puoi usare per definire lo stile delle tue pagine e app. L'ho scritto per aiutarti a essere a tuo agio con il CSS e aiutarti a essere subito operativo per l'utilizzo di questo strumento stupendo che ti permette di creare dei design fantastici sul web. Spero di aver raggiunto questo obiettivo.

Clicca qui per scaricare questo manuale in versione PDF / ePub / Mobi (versione originale inglese)

Flavio