Corso di CSS / Layout CSS fluidi con min(), max-width e clamp()
Un layout fluido permette alle dimensioni di adattarsi allo spazio disponibile imponendo al contempo dei limiti utili. Larghezze relative, max-width e funzioni come clamp() possono mantenere il contenuto leggibile senza forzare le stesse dimensioni fisse su ogni schermo.
Separa la larghezza del viewport dalla larghezza disponibile
L'area in cui una pagina web viene visualizzata nel browser è chiamata viewport. Tuttavia, la larghezza disponibile per le card all'interno del corpo potrebbe essere inferiore a quella del viewport. Questo perché la card deve adattarsi allo spazio rimanente escludendo il margine del genitore, lo spazio dalle altre colonne e il limite massimo di larghezza.
La percentuale in width: 100% utilizza la larghezza dell'area base circostante l'elemento in un tipico layout a blocchi. 100vw si basa sulla larghezza del viewport, quindi anche se lo metti all'interno di una piccola card può essere grande quanto l'intero schermo. Quando si aggiungono barre di scorrimento verticali e margini esterni, può verificarsi un overflow orizzontale. Per la larghezza degli elementi all'interno del corpo, considera prima le percentuali o la dimensione automatica.
| designazione | genitori stretti | genitori larghi | Standard di utilizzo |
|---|---|---|---|
| width: 48rem | Può essere più grande dei genitori | Mantieni 48rem | Non adatto come valore predefinito per il testo che può essere accorciato |
| width: 100% | Ridotto per corrispondere ai genitori | Continua ad aumentare fino alla larghezza del genitore | Elementi che devono riempire il genitore |
| width: 100%; max-width: 48rem | Ridotto a meno di 48rem | Fino a 48rem | Testo che richiede una larghezza di lettura limitata |
| min-width: 48rem | Non si riduce sotto i 48rem | Deciso secondo diverse regole di dimensione | Usare solo quando è richiesta una dimensione minima |
Vincolare e centrare l'area di contenuto
*, *::before, *::after { box-sizing: border-box; }
.content {
width: 100%;
max-width: 48rem;
margin-inline: auto;
padding-inline: 1rem;
}
Con border-box, padding e bordi si adattano all'interno della larghezza dichiarata. Se il font radice è 16px e il genitore è largo 390px, la larghezza esterna di questa casella di contenuto è 390px e il suo padding di 16px per lato lascia 358px per il contenuto. Con una larghezza del genitore di 1000px, la larghezza esterna si ferma a 768px e i margini automatici la centrano. Per ulteriori dettagli, vedere Dimensioni CSS, limiti min/max e box-sizing.
Applicare content-box allo stesso elemento aggiungerà padding a width: 100%, rendendolo più largo del suo genitore. D'altra parte, i margini non sono inclusi nemmeno nel border-box. Quando si specificano width: 100% e margini fissi su entrambi i lati insieme, è necessario controllare la somma totale. Se min-width e max-width entrano in conflitto, controlla anche min-width, poiché il min-width potrebbe farlo diventare più grande.
Usa min() e clamp()
min() seleziona il valore più piccolo tra i candidati. width: min(100%, 48rem) utilizza il valore minore tra la larghezza del genitore e 48rem, quindi i limiti di larghezza 100% e massima specificati in precedenza possono essere espressi in una sola dichiarazione.
.content { width: min(100%, 48rem); }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); }
clamp(minimum, preferred, maximum) usa il valore preferito mantenendolo tra il minimo e il massimo; non calcola una media aritmetica. Nel titolo sopra, rem si basa sulla dimensione del font radice e vw si basa sull'1% della larghezza della viewport. Se la dimensione radice è 16px, il minimo è 24px, il massimo è 40px e il valore preferito è 16px più il 2% della larghezza dello schermo.
| larghezza della viewport | Calcola il valore centrale | dimensione reale del titolo |
|---|---|---|
| 320px | 16 + 6,4 = 22,4px | Minimo 24px |
| 600px | 16 + 12 = 28px | 28px |
| 1200px | 16 + 24 = 40px | 40px |
| 1600px | 16 + 32 = 48px | Massimo 40px |
Se rendi il testo del corpo dipendente esclusivamente dalla larghezza dello schermo, potrebbe diventare troppo piccolo su schermi stretti o in situazioni con ingrandimento. Quando usi dimensioni fluide nei titoli, un buon punto di partenza è avere un limite inferiore leggibile e mantenere il corpo del testo a una dimensione basata su rem. Il fatto che tu abbia incluso un termine rem non garantisce automaticamente la leggibilità con l’ingrandimento, quindi dovrai controllare anche il risultato effettivo dello zoom del browser e le impostazioni predefinite del font. Puoi controllare il ruolo di ogni argomento nella definizione clamp() di MDN e nella spiegazione sull'accessibilità.
Esegui l'esempio di scheda fluida e immagine
Salva il seguente codice come fluid-size.html in UTF-8 e aprilo nel tuo browser. L’immagine è incorporata nel file sotto forma di dati SVG, quindi non c'è bisogno di scaricare un'immagine separata o una libreria esterna. Confronta la larghezza del corpo, il numero di colonne della scheda e la dimensione del titolo su uno schermo ampio e su uno schermo stretto di circa 390px. Se vuoi posizionare più schede in modo flessibile, dai un'occhiata a CSS Grid: repeat, auto-fit, auto-fill e aree per sapere come impostare la larghezza minima per le colonne.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>fluid-size.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 48rem); margin-inline: auto; padding: 1rem; }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); line-height: 1.3; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 1rem; }
.card { min-width: 0; padding: 1rem; background: #e8f3fa; overflow-wrap: anywhere; }
.card img { display: block; max-width: 100%; height: auto; margin-bottom: 1rem; }
.token { font-family: monospace; }
</style>
</head>
<body>
<main class="content">
<h1>Size elements to fit the screen and content</h1>
<p>The content is at most 48rem wide and shrinks to fit its parent on smaller screens.</p>
<div class="cards">
<article class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22400%22%20height%3D%22300%22%20viewBox%3D%220%200%20400%20300%22%3E%3Crect%20width%3D%22400%22%20height%3D%22300%22%20fill%3D%22%23287699%22%2F%3E%3Crect%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%23205c32%22%2F%3E%3Crect%20y%3D%22265%22%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%239e3131%22%2F%3E%3Ccircle%20cx%3D%22200%22%20cy%3D%22150%22%20r%3D%2270%22%20fill%3D%22%23f6ae4c%22%2F%3E%3Crect%20x%3D%2212%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3Crect%20x%3D%22358%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E" width="400" height="300" alt="Practice drawing with upper and lower bands and center circle"><h2>card with picture</h2><p>The image stays within the card width and preserves its original aspect ratio.</p></article>
<article class="card"><h2>A heading and description that wrap onto several lines</h2><p>Without a fixed height, the card grows as its text gets longer.</p></article>
<article class="card"><h2>Long identifier</h2><p class="token">ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></article>
</div></main>
</body>
</html>
L’espressione minmax(min(100%, 14rem), 1fr) usata per le colonne utilizza una larghezza minima predefinita di 14rem, ma se il genitore è più stretto, viene limitata al 100% della larghezza del genitore. auto-fit crea una colonna in cui si può inserire contenuto, e la larghezza rimanente viene divisa in colonne da 1fr. A causa del padding interno della scheda, la larghezza effettiva del testo e delle immagini è più piccola della larghezza esterna della card. Non giudicare il numero di colonne dal nome del dispositivo, ma dalla larghezza disponibile del genitore.
min-width: 0 rimuove un vincolo di dimensione minima che potrebbe impedire alla card di restringersi. overflow-wrap: anywhere fornisce interruzioni all'interno di un URL lungo o di un identificatore quando necessario. Hanno ruoli diversi: permettere al box di restringersi non fa di per sé andare a capo il suo testo. L'andare a capo cambia la presentazione, non il valore della stringa copiata.
Testare una modifica delle dimensioni alla volta
- Ridurre lo schermo a 390px. Il testo dovrebbe adattarsi allo schermo, la scheda dovrebbe essere verticale e le bande sopra e sotto l'immagine e il cerchio al centro dovrebbero essere tutte visibili.
- Cambiare solo la larghezza di
.contentin48rem. Dopo aver verificato perché il testo fuoriesce sullo schermo stretto, riportarlo amin(100%, 48rem). - Modificare solo il valore massimo del titolo in
3reme osservare la differenza su uno schermo più ampio. Calcolare il valore centrale spiega perché gli schermi stretti non cambiano dimensione; al termine ripristina 2.5rem. - Rimuove solo
overflow-wrap: anywhereda.card. Verifica se gli identificatori lunghi fuoriescono dalla scheda, poi ripristina la dichiarazione. Gli esperimenti successivi per modificare la dimensione della radice e l'ingrandimento del browser sono registrati in condizioni separate.
Prima di inserire overflow-x: hidden, che nasconde l'overflow, nell'intera pagina, controlla la larghezza, il margine, la larghezza minima e la stringa. Se lo nascondi dalla vista, il contenuto o gli elementi operativi potrebbero essere tagliati senza risolvere la causa. Per i principi di base della configurazione responsive, puoi anche fare riferimento alla guida al design responsive di MDN.




