Cosa fa clamp()
clamp(MIN, PREFERRED, MAX) prende tre valori e restituisce quello centrale, purché resti tra gli altri due. L'uso classico è un titolo che cresce con lo schermo ma si ferma a limiti sensati, senza media query:
Il valore preferito è 1rem + 3vw: 16px più il 3% della larghezza. In un'anteprima larga 800px fa 16 + 24 = 40px, che sta tra 24px (1.5rem) e 48px (3rem), quindi il titolo è di 40px. Su un telefono da 320px il valore preferito è 25.6px. Oltre i 1067px supererebbe i 48px, quindi si ferma a 48px. Ridimensiona la finestra per vedere il numero cambiare; qui vw è una percentuale della larghezza del riquadro di anteprima.
Vederlo senza ridimensionare la finestra
vw segue il viewport, che non puoi cambiare facilmente mentre leggi. Le unità delle container query seguono invece un contenitore: cqi è l'1% della larghezza del contenitore. Trascina il cursore per cambiare il box, e lo stesso tipo di clamp() reagisce:
Porta il cursore all'inizio e il titolo si ferma a 20px (il MIN). Portalo alla fine e si ferma a 40px (il MAX). In mezzo segue 0.5rem + 6cqi. È lo stesso meccanismo della versione con vw, con un righello più piccolo.
I tre argomenti
font-size: clamp(1rem, 0.8rem + 1vw, 1.5rem);
/* MIN PREFERRED MAX */
| Argomento | Ruolo | Unità tipica |
|---|---|---|
| MIN | il valore più piccolo ammesso | rem |
| PREFERRED | il valore che cambia con lo schermo | rem + vw (o cqi) |
| MAX | il valore più grande ammesso | rem |
I calcoli funzionano dentro ogni argomento senza scrivere calc(): 1rem + 2vw va bene così com'è. + e - richiedono uno spazio su entrambi i lati, altrimenti l'intera dichiarazione non è valida.
Se MIN è maggiore di MAX, vince MIN: clamp(3rem, 5vw, 2rem) vale sempre 3rem.
Calcolare il valore centrale
Per far crescere un font da 16px su uno schermo da 320px a 24px su uno schermo da 1280px:
- Pendenza: (24 − 16) ÷ (1280 − 320) = 8 ÷ 960 = 0.00833, cioè 0.833vw (vw è ogni 100px).
- Punto di partenza: 16px − 0.00833 × 320px = 13.33px, cioè 0.833rem.
- Metti i limiti attorno:
font-size: clamp(1rem, 0.833rem + 0.833vw, 1.5rem);
A 320px di larghezza dà 13.33 + 2.67 = 16px, a 1280px dà 13.33 + 10.67 = 24px, e fuori da quell'intervallo resta ai limiti. I "calcolatori di clamp" online fanno esattamente questa aritmetica.
min() e max()
clamp() è la combinazione di due funzioni più semplici:
min(a, b)restituisce il valore più piccolo, quindi imposta un limite superiore.max(a, b)restituisce il valore più grande, quindi imposta un limite inferiore.clamp(MIN, VAL, MAX)equivale amax(MIN, min(VAL, MAX)).
All'inizio i nomi sembrano al contrario: per dire "al massimo 600px" si usa min().
Nell'anteprima larga la prima scheda si ferma a 420px. Dentro il genitore da 260px, 100% è il valore più piccolo, quindi la seconda scheda è di 260px. max(12px, 3%) dà alla prima scheda il 3% della larghezza del genitore (il body: circa 23.5px in un'anteprima da 800px), e alla seconda 12px, perché il 3% di 260px (7.8px) è sotto la soglia minima.
width: min(100%, 420px) sostituisce in una sola dichiarazione la vecchia coppia width: 100%; max-width: 420px;.
Oltre i font: spaziature e larghezze
clamp() funziona in qualsiasi proprietà che accetti una lunghezza. Le percentuali nel valore centrale rendono un componente fluido rispetto al genitore invece che al viewport:
Nel genitore da 300px la scheda è larga 240px (80%) con 15px di padding (il 5% di 300px). Nel genitore da 760px l'80% sarebbe 608px, quindi la scheda si ferma al massimo di 520px, e il 5% di 760px è 38px, quindi il padding si ferma a 32px.
Accessibilità: tieni rem nel valore centrale
Una dimensione del font fatta solo di vw, come font-size: 5vw, non cresce quando chi legge aumenta la dimensione predefinita del font nelle impostazioni del browser, e non cresce nemmeno con lo zoom, perché lo zoom rende il viewport più stretto in pixel CSS. Aggiungere una parte in rem (1rem + 2vw) e limiti in rem mantiene il testo legato all'impostazione di chi legge. La pagina sulle unità spiega rem e vw nel dettaglio.
Errori comuni
- Usare
min()per un minimo.min()sceglie il valore più piccolo, cioè un limite superiore. Per "almeno 12px", usamax(12px, ...). - Nessuno spazio attorno a
+o-.clamp(1rem, 1rem+2vw, 3rem)non è valido, e la proprietà torna al valore precedente. - Solo
vwal centro. Il testo ignora allora l'impostazione del font di chi legge. Aggiungi un termine inrem. - MIN maggiore di MAX. Il risultato è sempre MIN, e raramente è ciò che si voleva.
- Limiti in
pxper le dimensioni del font. Bloccano il testo anche per chi ne ha bisogno più grande. Usarem.
Domande frequenti
Cosa fa clamp() in CSS?
clamp(MIN, PREFERRED, MAX) usa il valore preferito finché resta tra i due limiti, altrimenti il limite più vicino. font-size: clamp(1rem, 4vw, 2rem) segue il 4% della larghezza del viewport ma non scende mai sotto 1rem né sale sopra 2rem.
Come creo una dimensione del font responsive con clamp?
Metti un valore basato sul viewport al centro e limiti fissi ai lati, e aggiungi rem al valore centrale così il testo segue ancora la dimensione del font scelta da chi legge: font-size: clamp(1.5rem, 1rem + 2vw, 3rem);.
Cosa succede se in clamp() il minimo è maggiore del massimo?
Vince il minimo. clamp(3rem, 5vw, 2rem) vale sempre 3rem, perché clamp() applica il minimo dopo il massimo.
Che differenza c'è tra min() e max() in CSS?
min() restituisce il più piccolo dei suoi valori, quindi fa da limite superiore: width: min(100%, 600px) non supera mai i 600px. max() restituisce il più grande, quindi fa da limite inferiore: font-size: max(1rem, 2vw) non scende mai sotto 1rem.
clamp() è supportato da tutti i browser?
Sì, clamp(), min() e max() funzionano in tutte le versioni attuali di Chrome, Edge, Firefox e Safari, e si possono usare in qualsiasi proprietà che accetti una lunghezza, un numero, una percentuale o un angolo.