Menu

rem vs em vs px: unità CSS, percentuali, vw e vh

rem è relativo alla dimensione del font della radice, em a quella dell'elemento stesso, px è fisso e % dipende dalla proprietà. Guarda ogni unità misurata in una demo annidata, perché em si moltiplica, quando usare l'una o l'altra e come funzionano vw, vh e dvh.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

rem vs em in una demo annidata

rem è relativo alla dimensione del font della radice (l'elemento <html>, 16px di default). em è relativo alla dimensione del font corrente, che per font-size significa quella del genitore. Annida la stessa classe tre volte e la differenza si vede:

Le dimensioni stampate sono quelle calcolate dal browser. Ogni 1.25em moltiplica quella del genitore: 20px, poi 25px, poi 31.25px. Ogni 1.25rem guarda solo la radice: 20px, 20px, 20px. È questo effetto moltiplicativo il motivo per cui le dimensioni del font in em sfuggono di mano in liste e menu annidati, e per cui la maggior parte dei siti imposta le dimensioni del font in rem.

A cosa è relativa ogni unità

UnitàRelativa a1 unità di default
pxniente (un pixel CSS)1px
remla dimensione del font dell'elemento radice (html)16px
emla dimensione del font dell'elemento; per font-size stesso, quella del genitore16px al livello più alto
%dipende dalla proprietà (vedi sotto)
vw / vhl'1% della larghezza / altezza del viewport
dvh, svh, lvhl'1% dell'altezza dinamica, piccola o grande del viewport
vmin / vmaxl'1% del lato minore / maggiore del viewport
chla larghezza dello "0" nel font correntecirca mezzo em
exl'altezza della x nel font correntecirca mezzo em

Un pixel CSS non è un pixel del dispositivo: su un telefono con schermo 3x, 1px è largo 3 pixel del dispositivo. Mantiene più o meno la stessa dimensione visiva su tutti gli schermi, ed è per questo che px va ancora bene per bordi e ombre.

em per spaziature che scalano con il testo

em non serve solo per le dimensioni del font. Su padding, margin, width o border-radius significa "volte la dimensione del font di questo elemento". Così una sola classe di pulsante funziona a qualsiasi dimensione:

Il padding di ogni pulsante è metà della sua dimensione del font in verticale e una dimensione del font in orizzontale, quindi i tre sembrano lo stesso pulsante in tre taglie. Con un padding in px ti servirebbe una regola di padding diversa per ogni taglia.

Nota che i pulsanti non ereditano di default la dimensione del font della pagina (i browser danno ai controlli dei form la loro), quindi qui il pulsante centrale misura 13.33px in Chrome, non 16px. Aggiungi font: inherit a pulsanti e input quando vuoi che corrispondano alla pagina.

Percentuali: dipende dalla proprietà

% non ha un significato unico. Ogni proprietà definisce di cosa è una percentuale:

Proprietà% è relativo a
width, max-width, left, rightla larghezza del genitore (del blocco contenitore)
height, top, bottoml'altezza del genitore, e solo se il genitore ha un'altezza impostata
padding, margin (tutti e quattro i lati)la larghezza del genitore
font-sizela dimensione del font del genitore (150% = 1.5em)
line-heightla dimensione del font dell'elemento stesso
transform: translate()la dimensione dell'elemento stesso

width: 50% sono 200px, metà del genitore. padding-top: 5% sono 20px: il 5% della larghezza del genitore, non della sua altezza. E height: 50% non fa nulla, perché il genitore non ha un'altezza impostata, quindi il figlio è alto solo quanto il suo testo più quel padding. La pagina su width e height spiega questa regola nel dettaglio.

vw, vh e la barra degli indirizzi su mobile

1vw è l'1% della larghezza del viewport e 1vh l'1% della sua altezza. Sono utili per sezioni a schermo intero e per dimensioni fluide (spesso dentro clamp()). Sui telefoni, vh ha un tranello: la barra degli indirizzi del browser entra ed esce mentre scorri, e 100vh è l'altezza senza la barra, quindi un hero con height: 100vh resta tagliato in basso quando la barra è visibile. Le unità più recenti risolvono il problema:

UnitàAltezza usata
100vhil viewport grande (barre nascoste) nella maggior parte dei browser mobili
100svhil viewport piccolo (barre visibili): ci sta sempre
100lvhil viewport grande, in modo esplicito
100dvhil viewport dinamico: cambia mentre le barre si muovono
.hero {
  min-height: 100vh;  /* fallback for older browsers */
  min-height: 100svh; /* fits the screen even with the address bar visible */
}

Anche vw ha il suo tranello: 100vw include la larghezza di una barra di scorrimento verticale quando questa occupa spazio (come su Windows), quindi width: 100vw può essere più largo della pagina e aggiungere una barra di scorrimento orizzontale. Usa width: 100% per "tutta la larghezza del genitore".

ch per una lunghezza di riga leggibile

ch è la larghezza del carattere "0", quindi max-width: 65ch limita un paragrafo a circa 65 caratteri per riga, una lunghezza di lettura comoda, con qualsiasi dimensione del font:

Quale unità usare

PerUsaPerché
Dimensioni del fontremCoerente ovunque, rispetta l'impostazione della dimensione del font del lettore
Padding e gap nei componentirem o emem quando deve crescere con il testo del componente stesso
Bordi, linee sottili, ombrepxDevono restare sottili con qualsiasi dimensione del font
Larghezze di layout%, fr, max-width in rem o chSeguono il contenitore, limitano la lunghezza della riga
Sezioni a schermo interosvh / dvh (con vh come fallback)Gestiscono le barre degli indirizzi su mobile
Tipografia fluidaclamp() che combina rem e vwCresce con lo schermo entro dei limiti

Perché rem rispetta i lettori e px no

I browser hanno un'impostazione per la dimensione del font predefinita, usata da chi ha bisogno di un testo più grande. Cambia la dimensione del font della radice, quindi tutto ciò che è in rem e em cresce di conseguenza. Un font-size: 14px resta 14px qualunque cosa abbia scelto il lettore. Anche lo zoom del browser scala i px, ma l'impostazione della dimensione del font è quella su cui contano molti lettori. È il motivo principale per impostare le dimensioni del font in rem.

Alcuni siti impostano html { font-size: 62.5%; } così 1rem vale 10px e i calcoli sono più facili. Rispetta comunque l'impostazione del lettore (il 62.5% di quello che ha scelto), ma ricordati di impostare un font-size leggibile su body, altrimenti ogni elemento senza una dimensione propria mostra testo da 10px.

Errori comuni

  • Dimensioni del font in em in elementi annidati. Si moltiplicano a ogni livello. Usa rem per le dimensioni del font.
  • Un height: 50% che non fa nulla. Il genitore ha bisogno di un'altezza impostata perché un'altezza in percentuale funzioni.
  • Aspettarsi che padding-top: 10% segua l'altezza del genitore. Le percentuali di padding e margin verticali usano la larghezza del genitore.
  • width: 100vw che causa una barra di scorrimento orizzontale. Include la barra di scorrimento. Usa 100%.
  • Un height: 100vh tagliato sui telefoni. Usa 100svh o 100dvh.
  • Impostare html { font-size: 12px }. Un valore in px sulla radice sovrascrive l'impostazione della dimensione del font del lettore in tutta la pagina. Lascia stare la radice o usa una percentuale.

Domande frequenti

Che differenza c'è tra rem ed em?

rem è relativo alla dimensione del font dell'elemento radice (<html>), quindi 1.5rem ha la stessa dimensione in tutta la pagina. em è relativo alla dimensione del font dell'elemento stesso (per font-size, a quella del genitore), quindi si moltiplica quando gli elementi sono annidati.

Quanti pixel è 1rem?

16px di default, perché i browser impostano la dimensione del font della radice a 16px. Se l'utente aumenta la dimensione del font predefinita nelle impostazioni del browser, o se imposti html { font-size: ... }, 1rem cambia di conseguenza.

Meglio rem o px per la dimensione del font?

Usa rem per le dimensioni del font. Rispetta l'impostazione della dimensione del font predefinita del lettore nel browser, che px ignora. Lo zoom del browser scala entrambi, ma non tutti i lettori usano lo zoom.

Quando usare em invece di rem?

Usa em per le spaziature che devono scalare con il testo dell'elemento stesso, come il padding di un pulsante o la dimensione di un'icona accanto al testo. Così la stessa classe si vede bene con qualsiasi dimensione del font. Usa rem per le dimensioni del font e le spaziature a livello di pagina, così niente si moltiplica.

Che differenza c'è tra 100vh e 100dvh?

Nei browser mobili, 100vh è l'altezza con la barra degli indirizzi nascosta, quindi una sezione di 100vh è più alta dello schermo visibile mentre la barra è mostrata. 100dvh (altezza dinamica del viewport) segue la barra quando compare e scompare, e 100svh è sempre l'altezza più piccola.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA