Tipografia reattiva e fluida con le funzionalità CSS di base

Data di pubblicazione: 16 dicembre 2025

Il web design adattabile è un approccio alla creazione di siti web che abbiano un bell'aspetto e funzionino bene su una vasta gamma di browser, dimensioni dell'area visibile, dispositivi e preferenze utente. Se applicato alla tipografia, il problema principale è spesso l'aggiustamento di font-size in base alla larghezza del browser, il che può avere implicazioni anche per i valori di spaziatura come line-height e margin.

In qualità di designer, è logico pensare allo spazio disponibile nel browser e regolare la tipografia di conseguenza. È anche importante ricordare che utenti diversi avranno esigenze di font-size diverse su una vasta gamma di dispositivi, a seconda di circostanze personali al di fuori della tua portata o consapevolezza. Pertanto, è pericoloso fare qualsiasi cosa che sottragga il controllo del risultato finale all'utente. Esistono due input principali che le persone possono utilizzare per influire sulle dimensioni dei caratteri durante la navigazione sul web:

  • Fornire una preferenza font-size predefinita per tutti i siti web.
  • Aumentare o diminuire lo zoom in base al sito.

Lo scopo di questa demo è rendere la tipografia reattiva sia alle dimensioni dell'area visibile del browser sia agli input dell'utente. Tuttavia, è importante capire che più la tipografia risponde al viewport, meno risponderà alle preferenze dell'utente. Se intendi implementare la tipografia reattiva, è importante farlo con attenzione e verificare che i risultati siano ancora accessibili.

Negozia un font-size di base in base alle preferenze dell'utente

Il primo passaggio per definire qualsiasi tipografia online è negoziare una dimensione iniziale del carattere in base alla preferenza font-size dell'utente. Verrà utilizzato per la maggior parte del testo della pagina e come base per altre dimensioni dei caratteri, ad esempio le intestazioni. L'opzione più semplice è concedere all'utente il controllo completo utilizzando 1em, senza alcuna modifica. Se non imposti altri valori font-size, 1em si riferisce alla preferenza dell'utente. All'altra estremità dello spettro, l'impostazione di un valore font-size in pixel o altre unità assolute (e persino unità relative alla finestra) sostituirà completamente l'utente, il che è da evitare.

Tuttavia, casi d'uso diversi richiedono tipografie diverse. Un articolo potrebbe essere più facile da leggere con un testo grande, mentre i siti con molti dati potrebbero richiedere un design più compatto con un testo più piccolo. In entrambi i casi, potresti voler suggerire un valore predefinito che si adatti al design, consentendo comunque all'utente di modificare il risultato in base alla sua situazione specifica.

Opzione 1: calcola un moltiplicatore in base a ipotesi

Un compromesso comune è definire un font-size aggiustato in unità em o %, rispetto al font-size predefinito dell'utente. In genere, questo approccio parte dal presupposto che i browser forniscano un valore predefinito 16px e che la maggior parte degli utenti lo lasci invariato. Se ritieni che una dimensione del carattere di 20px sia più adatta al tuo sito, un font-size di 1.25em o 125% di solito ti darà il risultato che desideri:

html {
  /* 20px preferred, 16px expected: 20/16 = 1.25 */
  font-size: 1.25em;
}

Qui potresti anche utilizzare una funzione calc() per mostrare il calcolo, ma devi comunque conoscere l'equazione: la dimensione target divisa per la dimensione prevista, moltiplicata per 1em:

html {
  font-size: calc(20 / 16 * 1em);
}

Gli utenti con una preferenza maggiore o minore avranno una certa capacità di influire sul risultato, poiché il valore predefinito è ora relativo al loro, ovvero 1,25 volte la loro preferenza in questo caso. Tuttavia, può essere strano se sia tu che l'utente richiedete entrambi i valori predefiniti di 20px e il risultato è 25px, ovvero i tempi predefiniti aggiustati moltiplicati di nuovo per 1,25, una dimensione che nessuno ha richiesto.

Opzione 2: lascia che sia clamp() a occuparsene

Un approccio più sfumato prevede l'utilizzo di funzioni di confronto CSS, senza alcun calcolo. Anziché presupporre che 1 em sia uguale a 16px ed eseguire conversioni inaffidabili da px a em, puoi considerare 1em come una variabile che fa riferimento alla preferenza dell'utente. Indipendentemente dal valore in pixel che rappresenta 1em, un font-size di max(1em, 20px) restituirà sempre il valore più grande tra la preferenza di progettazione (20px) e la preferenza dell'utente (1em). In questo modo, l'utente può scegliere dimensioni del carattere più grandi, ma non più piccole.

Passando a una funzione clamp(), puoi consentire all'utente di scalare in entrambe le direzioni quando le dimensioni preferite si discostano troppo da quelle predefinite scelte. Ad esempio, un font-size di clamp(1em, 20px, 1.25em) verrà impostato su 20px, a condizione che sia superiore al valore predefinito dell'utente, ma non superiore a 125% del valore predefinito.

In questo modo, il tuo design ha la priorità quando è vicino alla preferenza dell'utente, ma l'utente ha comunque la priorità quando la sua preferenza non rientra nell'intervallo specificato. Non sono coinvolti calcoli di conversione, non vengono fatte ipotesi sulle dimensioni delle preferenze dell'utente e non vengono moltiplicati i valori del designer e dell'utente.

Se lo imposti come font-size principale nell'elemento html, ora puoi fare riferimento a 1rem in qualsiasi punto del sito, in quanto è la dimensione di base negoziata.

Aggiungere la reattività

Per rendere questo font-size reattivo all'area visibile, un'opzione è aggiungere punti di interruzione delle media query (o delle container query). Ad esempio, puoi modificare il valore bloccato in base alle dimensioni dello schermo:

html {
  font-size: clamp(1em, var(--base-font-size, 16px), 1.25em);
  @media (width > 30em) { --base-font-size: 18px; }
  @media (width > 45em) { --base-font-size: 20px; }
}

L'altra opzione è aggiungere unità di visualizzazione o contenitore al valore di base statico:

html {
  font-size: clamp(1em, 16px + 0.25vw, 1.25em);
}

Le unità vw (larghezza dell'area visibile) o vi (dimensione in linea dell'area visibile) rappresentano l'1% dell'area visibile totale, ovvero la parte del browser che esegue il rendering del tuo sito. Allo stesso modo, le unità cqw e cqi rappresentano l'1% di un contenitore di dimensioni in linea nella pagina. Per maggiori dettagli, consulta la demo di query e unità contenitore.

Questo approccio viene spesso definito tipografia fluida, poiché la variazione di font-size è costante in un intervallo di larghezze della finestra, anziché passare da un valore all'altro in corrispondenza dei punti di interruzione dei media o dei contenitori. Tuttavia, non farti distrarre dalla fluidità della transizione: questa distinzione è generalmente visibile solo nei test, se regoli le dimensioni della finestra in modo uniforme. Questo effetto è raramente (se non mai) visto dagli utenti. Anche se gli utenti possono modificare regolarmente le dimensioni del browser o il livello di zoom, dovrebbero apportare queste modifiche in modo lento e fluido per notare la differenza tra un punto di interruzione e un'unità viewport. Influisce solo sulla transizione, non sul risultato dopo il ridimensionamento.

Il vantaggio principale del dimensionamento fluido dei caratteri è che non è necessario calcolare o specificare manualmente i punti di interruzione, fornendo un risultato interpolato per qualsiasi dimensione. Imposti solo il punto di partenza (16px) e il tasso di variazione (0.25vw fornirà un aumento di 0.25px in font-size per ogni aumento di 100px nella finestra), nonché, se necessario, i valori minimo e massimo. Quando la larghezza del riquadro è 1000px, il valore di font-size sarà 16px + 2.5px o 18.5px, ma questo calcolo viene gestito interamente dal browser. Questo è l'approccio utilizzato nella demo, che utilizza le unità cqi per mostrare la reattività basata sui contenitori. Se utilizzato sull'elemento radice (html), dove non è definito alcun contenitore, le unità cqi fanno comunque riferimento alle dimensioni del riquadro.

Se preferisci pensare in termini di font-size specificato a una determinata dimensione dell'area visibile, ti consigliamo di utilizzare l'approccio più diretto della media query, che è un po' più chiaro. Le cose si complicano quando provi a calcolare le unità di viewport in base ai punti di interruzione previsti. Molte persone lo fanno copiando e incollando i valori da strumenti di terze parti, ma il codice risultante è molto più difficile da comprendere o modificare direttamente. In generale, con CSS, l'opzione migliore è quella che esprime più chiaramente le tue intenzioni.

Avviso: le modifiche dell'area visibile non significano sempre la stessa cosa.

Sebbene le query supporti e le unità vi vengano applicate in modi diversi, entrambi gli approcci si basano sulla stessa misurazione dell'area visibile. Se l'area visibile ha una larghezza di 600px, 100vw sarà uguale a 600px e verranno applicati gli stili all'interno della media query (width > 500px).

Ma cosa significa che l'area visibile è larga 600px? In realtà, un pixel non ha una dimensione fissa con un unico significato in tutte le situazioni. Anche se sembra naturale che una finestra con meno pixel sia su uno schermo più piccolo (come un telefono) o in una finestra del browser stretta, non è un'ipotesi affidabile. Infatti, aumentare lo zoom e ridurre le dimensioni della finestra del browser avranno lo stesso impatto sulla larghezza dell'area visibile misurata. Un'azione (zoom) modifica le dimensioni di un pixel, mentre l'altra (ridimensionamento) modifica le dimensioni del browser stesso, ma entrambe modificano il numero di pixel in larghezza del browser. Ciò che otteniamo dalla misurazione dell'area visibile è una relazione tra le dimensioni in pixel correnti e la finestra del browser corrente.

Per l'utente, lo zoom e il ridimensionamento hanno scopi molto diversi. Un utente che modifica il livello di zoom sta cercando di ingrandire o ridurre i contenuti della pagina, mentre un utente che ridimensiona il browser sta solo gestendo lo spazio su schermi diversi. Anche se l'intent dell'utente è diverso, il risultato delle misurazioni CSS è lo stesso. Man mano che la finestra si rimpicciolisce o il pixel si ingrandisce, il numero di pixel lungo la larghezza del browser diminuisce.

Questo disallineamento rende inaffidabile la tipografia reattiva. Se il testo è impostato per essere ridimensionato solo in base a un'area visibile o a un contenitore, lo zoom dell'utente non avrà alcun effetto.

Se modifichi il valore dell'unità relativa al viewport in 1vw o 100vw, cambierà la relazione esatta tra le dimensioni del carattere e il viewport. Un carattere 1vw aumenterà di 1px per ogni 100px di dimensione dell'area visibile, mentre un carattere 100vw avrà esattamente le stesse dimensioni dell'area visibile. Puoi modificare questo valore per fare in modo che il carattere cresca più lentamente o più rapidamente rispetto al browser. Tuttavia, qualsiasi valore relativo all'area visibile rimarrà costante quando l'utente esegue lo zoom avanti o indietro, senza rispondere ai controlli utente.

Allo stesso modo, né 1vw100vw tengono conto del valore predefinito dell'utente font-size.

L'utilizzo di unità relative al viewport o al contenitore da sole per font-size è sempre ostile all'utente. Quando un font-size è completamente reattivo al suo contenitore, non può essere reattivo anche alle impostazioni predefinite o agli aggiustamenti dell'utente. Anche con le migliori intenzioni e salvaguardie, è meglio evitare di togliere agli utenti il controllo finale font-size. Non solo si tratta di un'esperienza utente negativa, ma può anche violare le linee guida per l'accessibilità, spesso richieste dalla legge. Nello specifico, la sezione 1.4.4 delle Web Content Accessibility Guidelines richiede che "il testo possa essere ridimensionato senza tecnologia assistiva fino al 200%".

Come assicurarsi che i valori di font-size rispondano allo zoom

Per garantire che un font-size relativo al viewport sia reattivo allo zoom, il valore relativo al viewport deve essere applicato come aggiustamento a un altro valore. È possibile farlo in CSS utilizzando la funzione calc() o qualsiasi altra funzione matematica che accetta calcoli, ad esempio min(), max() e clamp(). Un font-size di calc(16px + 1vw) si basa sia sulle dimensioni dell'area visibile sia sulle dimensioni attuali (relative allo zoom) di un pixel. Mentre l'unità vw non sarà interessata dallo zoom, il valore di base lo sarà.

Il risultato è un font-size che risponde sia alle dimensioni dell'area visibile sia alle impostazioni di zoom dell'utente. Se l'utente esegue lo zoom fino a 200%, il valore di base verrà visualizzato con una dimensione doppia (32px), mentre il valore adattabile rimane invariato. Un'area visibile 1000px inizialmente ti darebbe un font-size di 16px + 10px = 26px, ma con uno zoom 200%, le dimensioni del carattere aumenterebbero solo fino a 42px, poco più di 160%. Potrebbe non sembrare un problema estremo, ma più il tuo font-size si basa sulla finestra, meno efficace diventa lo zoom.

Sugli schermi piccoli, il font-size deriverà principalmente dal valore di base dei pixel e risponderà bene allo zoom. Tuttavia, sugli schermi più grandi, il dimensionamento della finestra diventa una frazione maggiore della dimensione del carattere visualizzato, rendendo lo zoom meno efficace. Ciò diventa particolarmente pericoloso quando lo zoom al 500% (il massimo nella maggior parte dei browser) non riesce più a fornire l'aumento del 200% delle dimensioni del carattere richiesto dalle WCAG 1.4.4, ma anche prima di questo punto, può essere frustrante che lo zoom diventi inefficace.

Grafico che mostra le dimensioni del carattere e l'efficacia dello zoom rispetto alla larghezza della finestra. Le dimensioni del carattere, calcolate come `calc(17px + 2.5vw)`, aumentano linearmente con la larghezza dell'area visibile. La linea dello zoom al 500%, che rappresenta lo zoom massimo possibile, mostra che lo zoom diventa meno efficace all'aumentare della larghezza del viewport, non riuscendo a fornire un aumento delle dimensioni del carattere del 200% oltre una larghezza del viewport di 2040 px.
L'asse orizzontale rappresenta le dimensioni dell'area visibile, da 0 a 2600px di larghezza. Anche l'asse verticale per font-size è in pixel e mostra il risultato di calc(17px + 2.5vw). La linea di zoom 500% utilizza lo stesso asse orizzontale della larghezza della finestra, ma considera l'asse verticale come percentuale.

Sul bordo sinistro del grafico (larghezza viewport 0), lo zoom 500% è completamente efficace. Tuttavia, l'efficacia diminuisce rapidamente all'aumentare delle dimensioni del browser e le unità viewport (non scalabili) diventano un fattore più importante nel font-size. Quando il browser ha una larghezza di 2040px, lo zoom massimo di 500% è in grado di aumentare la dimensione del carattere solo di 200%. Oltre questo punto, lo zoom effettivo dei caratteri 200% non è più possibile.

Spostando questo calcolo in una funzione clamp(), con valori minimi e massimi, puoi applicare limiti che garantiscano il testo con zoom. Secondo Maxwell Barvian:

Se la dimensione massima del carattere è inferiore o uguale a 2,5 volte la dimensione minima del carattere, il testo supererà sempre il criterio di successo WCAG 1.4.4, almeno su tutti i browser moderni.

Poiché le query @media e @container si basano sulle stesse misurazioni delle unità vw e cqw, si applica la stessa logica quando si utilizza un punto di interruzione per modificare le dimensioni del carattere. Quando l'aumento delle dimensioni è troppo drastico, lo zoom diventa inefficace. Puoi sperimentare il modo in cui questi valori interagiscono nella seguente visualizzazione:

Come assicurarsi che i valori di font-size rispondano ai valori predefiniti dell'utente

Tuttavia, calc(16px + 1vw) non risponde ancora alle impostazioni del carattere predefinito dell'utente. Per farlo, puoi impostare una base, ovvero valori minimi e massimi, utilizzando le unità em o rem anziché px. Se metti insieme tutti questi elementi, ottieni un risultato familiare che corrisponde alla demo collegata:

html {
  font-size: clamp(1em, 17px + 0.24vw, 1.125em);
}

Ricorda:

  • Il valore minimo e massimo utilizzano unità em, che si basano sulle preferenze dell'utente (e sono reattive allo zoom).
  • Il valore aggiuntivo vw viene mantenuto al minimo, in modo che lo zoom non sia troppo influenzato.
  • La dimensione massima (1.125em) è ben inferiore a 2,5 volte la dimensione minima (1em), il che garantisce che sia sempre possibile un valore font-size effettivo di 200%.

Scale tipografiche con pow()

La maggior parte dei design utilizza più di una dimensione del carattere. Una scala tipografica descrive la relazione tra più dimensioni dei caratteri. Può essere espressa come dimensione base e una serie di moltiplicatori per calcolare le altre dimensioni. CSS fornisce una scala tipografica integrata relativa alla parola chiave medium, che fa riferimento alla preferenza di dimensione del carattere dell'utente, o un valore predefinito di 16px. La scala delle parole chiave completa è:

  • xx-small: 3/5 (0,6)
  • x-small: 3/4 (0,75)
  • small: 8/9 (0,89)
  • medium: 1 (la dimensione di base per la moltiplicazione delle altre)
  • large: 6/5 (1.2)
  • x-large: 3/2 (1,5)
  • xx-large: 2/1 (2)
  • xxx-large: 3/1 (3)

Questa scala è relativa al valore predefinito dell'utente anziché alla radice font-size, quindi non funziona bene una volta modificata la radice font-size del tuo sito. La maggior parte degli autori finisce per ricreare una scala tipografica simile con proprietà personalizzate, a volte utilizzando gli stessi nomi delle taglie delle magliette e a volte preferendo una serie di passaggi su e giù per una scala matematica. Esistono molti strumenti di terze parti per generare queste scale in base a rapporti comuni, per lo più presi in prestito da una scala musicale occidentale:

html {
  /* musical ratios */
  --minor-second: calc(16/15);
  --major-second: calc(9/8);
  --minor-third: calc(6/5);
  --major-third: calc(5/4);
  --perfect-fourth: calc(4/3);
  --augmented-fourth: sqrt(2);
  --perfect-fifth: calc(3/2);
  --major-sixth: calc(5/3);

  /* the golden ratio*/
  --golden-ratio: calc((1 + sqrt(5)) / 2);
}

Tuttavia, non hai bisogno di strumenti esterni per creare la tua scala in CSS: la nuova funzione pow() può generare la scala per te, con 1rem come dimensione di base.

html {
  /* choose a ratio */
  --scale: 1.2;

  /* generate the scale using pow() */
  --xx-small: calc(1rem * pow(var(--scale), -0.5));
  --x-small: calc(1rem * pow(var(--scale), -0.25));
  --small: calc(1rem * pow(var(--scale), -0.125));
  --medium: 1rem;
  --large: calc(1rem * pow(var(--scale), 1));
  --x-large: calc(1rem * pow(var(--scale), 2));
  --xx-large: calc(1rem * pow(var(--scale), 3));
  --xxx-large: calc(1rem * pow(var(--scale), 4));

  /* change the ratio for different viewport sizes */
  @media (width > 50em) {
    --scale: var(--perfect-fourth);
  }
}

Non devi usare passaggi interi per mantenere la scala coerente. Infatti, la scala tipografica comune 12pt utilizza circa 5 frazioni per passaggio. Mentre le dimensioni grandi utilizzano passaggi interi nella scala, le dimensioni piccole utilizzano frazioni per scalare a una velocità inferiore.

I mixin e le funzioni CSS consentono di condensare ulteriormente questa logica, mentre altri strumenti integrati come progress() semplificano la creazione di scale che si adattano in modo fluido da un valore all'altro. ma non rientrano nell'ambito di questa demo.

Rispondere alle dimensioni dei contenitori in pagina

Puoi fare in modo che tutti questi calcoli funzionino nelle query sui contenitori utilizzando l'unità cqi al posto di vw o vi, ma è anche utile lasciare l'unità font-size dell'utente nell'elemento html, in modo che ogni contenitore di composizione tipografica possa fare riferimento a questa preferenza dell'utente come 1rem. Nella demo, noterai che l'intera scala tipografica viene applicata a body anziché all'elemento html principale per il tipo globale, quindi viene reimpostata in base alle dimensioni del contenitore per ogni elemento con l'attributo type-set.

Si tratta sempre di un compromesso con le dimensioni dei caratteri relative al contenitore. Ottieni un dimensionamento dei caratteri più fluido per ogni elemento nel contesto, ma a scapito di una coerenza a livello di pagina. Quale sia più importante per te dipende dalle specifiche del tuo caso d'uso. Ricorda che la tipografia fluida è un compromesso che rende meno efficaci i controlli utente come lo zoom.

Sebbene la tipografia adattabile e le scale tipografiche siano ottimi strumenti per i designer, non è necessario complicare le cose se non è necessario. Anche la scala tipografica predefinita e integrata dell'utente è un'ottima opzione. Tuttavia, se scegli la tipografia reattiva (o fluida), assicurati di testare il comportamento dei risultati in relazione a diverse impostazioni predefinite e di zoom dell'utente. Buon divertimento!