Un tuffo in profondità nell'adattamento degli oggetti e nelle dimensioni dello sfondo nei CSS

Pubblicato: 2022-03-10
Riepilogo rapido ↬ In questo articolo, analizzeremo come funzionano object-fit e background-size , quando possiamo usarli e perché, insieme ad alcuni casi d'uso pratici e consigli. Immergiamoci.

Non siamo sempre in grado di caricare immagini di dimensioni diverse per un elemento HTML. Se utilizziamo una larghezza e un'altezza che non sono proporzionali alle proporzioni dell'immagine, l'immagine potrebbe essere compressa o allungata. Non va bene e può essere risolto sia con object-fit for a img element sia usando background-size .

Per prima cosa, definiamo il problema. Considera la figura seguente:

Una bella foto e un'immagine schiacciata a confronto
Una bella foto che viene schiacciata quando viene utilizzata in un componente di una scheda. (Grande anteprima)

Perché sta succedendo?

Un'immagine avrà una proporzione e il browser riempirà la casella che la contiene con quell'immagine. Se le proporzioni dell'immagine sono diverse dalla larghezza e dall'altezza specificate, il risultato sarà un'immagine compressa o allungata.

Lo vediamo nella figura seguente:

Una bella foto e un'immagine allungata a confronto
Le proporzioni dell'immagine sono diverse dalla casella che la contiene e l'immagine viene allungata. (Grande anteprima)

La soluzione

Non è sempre necessario aggiungere un'immagine di dimensioni diverse quando le proporzioni dell'immagine non sono allineate con la larghezza e l'altezza dell'elemento contenitore. Prima di immergerti nelle soluzioni CSS, voglio mostrarti come lo facevamo nelle app di fotoritocco:

Esempio di un'immagine con i bordi superiore e inferiore ritagliati in una maschera
Per prima cosa, centravamo l'immagine verticalmente, quindi ritagliavamo una maschera. Ciò mantiene le proporzioni dell'immagine e ne impedisce la compressione. (Grande anteprima)

Ora che capiamo come funziona, vediamo come funziona nel browser. ( Avviso spoiler: è più facile! )

Adattamento object-fit CSS

La proprietà object-fit definisce come ridimensionare il contenuto di un elemento sostituito come img o video per adattarlo al suo contenitore. Il valore predefinito per object-fit è fill , che può comportare la compressione o l'allungamento di un'immagine.

Esaminiamo i possibili valori.

Altro dopo il salto! Continua a leggere sotto ↓

Possibili valori per object-fit

object-fit: contain

In questo caso, l'immagine verrà ridimensionata per adattarsi alle proporzioni del suo contenitore. Se le proporzioni dell'immagine non corrispondono a quelle del contenitore, verrà inserita nella cassetta delle lettere.

adatto all'oggetto: contenere
Quando si utilizza object-fit: contain , l'immagine verrà inserita in formato letterbox o ridimensionata di conseguenza. (Grande anteprima)

object-fit: cover

Qui, l'immagine verrà anche ridimensionata per adattarsi alle proporzioni del suo contenitore e, se le proporzioni dell'immagine non corrispondono a quelle del contenitore, verrà ritagliata per adattarla.

adatto all'oggetto: copertina
Quando si utilizza object-fit: cover , l'immagine verrà ritagliata per adattarla o ridimensionata di conseguenza. (Grande anteprima)

object-fit: fill

In questo modo, l'immagine verrà ridimensionata per adattarsi alle proporzioni del suo contenitore e, se le proporzioni dell'immagine non corrispondono a quelle del contenitore, verrà schiacciata o allungata. Non lo vogliamo.

adattamento all'oggetto: riempimento
Quando si utilizza object-fit: fill , l'immagine verrà compressa, allungata o ridimensionata di conseguenza. (Grande anteprima)

object-fit: none

In questo caso, l'immagine non verrà affatto ridimensionata, né allungata né schiacciata. Funziona come il valore di cover , ma non rispetta le proporzioni del suo contenitore.

adattamento all'oggetto: nessuno
Quando si utilizza object-fit: none , l'immagine non verrà ridimensionata se le sue dimensioni non sono le stesse. (Grande anteprima)

Oltre a object-fit , abbiamo anche la proprietà object-position , che è responsabile del posizionamento di un'immagine all'interno del suo contenitore.

Valori possibili per object-position

La proprietà object-position funziona in modo simile alla proprietà background-position dei CSS:

posizione dell'oggetto centro, sinistra, destra
Nella maggior parte dei casi, viene utilizzato il valore predefinito (cioè `centro` o `50% 50%`). (Grande anteprima)

Le parole chiave in top e in bottom funzionano anche quando le proporzioni del riquadro che lo contengono sono verticalmente più grandi:

posizione dell'oggetto in alto e in basso
Confronto object-position: top (a sinistra) e object-position: bottom (a destra). (Grande anteprima)

background-size CSS

Con background-size , la prima differenza è che abbiamo a che fare con lo sfondo, non con un elemento HTML ( img ).

Possibili valori per background-size

I possibili valori per background-size sono auto , contain e cover .

background-size: auto

Con auto , l'immagine rimarrà alla sua dimensione predefinita:

dimensione dello sfondo: automatica
Tieni presente che la dimensione predefinita a volte può risultare in un'immagine sfocata (se è troppo piccola). (Grande anteprima)

background-size: cover

Qui, l'immagine verrà ridimensionata per adattarsi al contenitore. Se le proporzioni non sono le stesse, l'immagine verrà mascherata per adattarla.

dimensione dello sfondo: copertina
Quando si utilizza background-size: cover , assicurarsi di considerare le proporzioni di un'immagine. (Grande anteprima)

background-size: contain

In questo caso, l'immagine verrà ridimensionata per adattarsi al contenitore. Se le proporzioni sono disattivate, l'immagine sarà in formato letterbox come mostrato nell'esempio successivo:

dimensione dello sfondo: contiene
background-size: contain ridimensiona l'immagine per adattarla al contenitore. (Grande anteprima)

Per quanto riguarda background-position , è simile a come funziona object-position . L'unica differenza è che la posizione predefinita di object-position è diversa da quella di background-position .

Quando non utilizzare object-fit o background-size

Se all'elemento o all'immagine viene assegnata un'altezza fissa e ha una background-size: cover o object-fit: cover applicata, ci sarà un punto in cui l'immagine sarà troppo ampia, perdendo così dettagli importanti che potrebbero influenzare il modo in cui l'utente percepisce l'immagine.

Considera il seguente esempio in cui all'immagine viene assegnata un'altezza fissa:

 .card__thumb { height: 220px; }
Un esempio in cui un'immagine è troppo larga in quanto ha un'altezza fissa e il contenitore della scheda è troppo largo
L'immagine mostrata a destra è troppo larga perché ha un'altezza fissa mentre il contenitore della carta è troppo largo. (Grande anteprima)

Se il contenitore della scheda è troppo largo, risulterà quello che vediamo a destra (un'immagine troppo ampia). Questo perché non stiamo specificando un rapporto di aspetto.

C'è solo una delle due correzioni per questo. Il primo è usare l'hack del padding per creare un rapporto intrinseco.

 .card__thumb { position: relative; padding-bottom: 75%; height: 0; } .card__thumb img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

La seconda soluzione consiste nell'usare la nuova proprietà CSS aspect-ratio . Usandolo, possiamo fare quanto segue:

 .card__thumb img { aspect-ratio: 4 / 3; }

Nota : ho già scritto in dettaglio sulla proprietà aspect-ratio nel caso tu voglia saperne di più: "Let's Learn About Aspect Ratio In CSS".

Casi d'uso ed esempi

Avatar utente

Un caso d'uso perfetto per object-fit: cover è avatar degli utenti. Le proporzioni consentite per un avatar sono spesso quadrate. Posizionare un'immagine in un contenitore quadrato potrebbe distorcere l'immagine.

Un avatar utente senza adattamento all'oggetto e con adattamento all'oggetto: copertina
Un confronto tra un avatar utente senza object-fit all'oggetto e con adattamento object-fit: cover . (Grande anteprima)
 .c-avatar { object-fit: cover; }

Elenco dei loghi

Elencare i clienti di un'azienda è importante. Utilizzeremo spesso i loghi per questo scopo. Poiché i loghi avranno dimensioni diverse, abbiamo bisogno di un modo per ridimensionarli senza distorcerli.

Per fortuna, object-fit: contain è una buona soluzione per questo.

 .logo__img { width: 150px; height: 80px; object-fit: contain; }
Un elenco di loghi: Airbnb, Domino's Pizza, Apple Pay, Amazon
L'uso object-fit: contain può aiutarci a ridimensionare i loghi dei clienti senza distorcerli. (Grande anteprima)

Anteprima dell'articolo

Questo è un caso d'uso molto comune. Il contenitore per la miniatura di un articolo potrebbe non avere sempre un'immagine con le stesse proporzioni. Questo problema dovrebbe essere risolto in primo luogo dal sistema di gestione dei contenuti (CMS), ma non sempre.

 .article__thumb { object-fit: cover; }
Miniatura dell'articolo
Regolazione delle miniature degli articoli con l'aiuto di object-fit: cover . (Grande anteprima)

Sfondo eroe

In questo caso d'uso, la decisione se utilizzare un elemento img o uno sfondo CSS dipenderà da quanto segue:

  • L'immagine è importante? Se il CSS è disabilitato per qualche motivo, vorremmo che l'utente vedesse l'immagine?
  • O lo scopo dell'immagine è meramente decorativo?

Sulla base della nostra risposta, possiamo decidere quale funzione utilizzare. Se l'immagine è importante :

Caso d'uso con uno sfondo da eroe
Supponiamo che l'immagine sia importante, perché è un sito web legato al cibo. (Grande anteprima)
 <section class="hero"> <img class="hero__thumb" src="thumb.jpg" alt="" /> </section>
 .hero { position: relative; } .hero__thumb { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; }

Se l'immagine è decorativa , possiamo utilizzare background-image :

 .hero { position: relative; background-image: linear-gradient(to top, #a34242, rgba(0,0,0,0), url("thumb.jpg"); background-repeat: no-repeat; background-size: cover; }

Il CSS è più breve in questo caso. Assicurati che qualsiasi testo posizionato sopra l'immagine sia leggibile e accessibile.

Aggiunta di uno sfondo a un'immagine con object-fit: contain

Sapevi che puoi aggiungere un colore di sfondo a img ? Ne trarremmo vantaggio quando si utilizza anche object-fit: contain .

Nell'esempio seguente, abbiamo una griglia di immagini. Quando le proporzioni dell'immagine e del contenitore sono diverse, verrà visualizzato il colore di sfondo.

 img { object-fit: contain; background-color: #def4fd; }
Aggiunta di un colore di sfondo a un'immagine con adattamento oggetto: contiene
Possiamo usare object-fit: contain per aggiungere un colore di sfondo a un'immagine. (Grande anteprima)

Elemento video

Hai mai avuto bisogno di un video come sfondo? Se è così, probabilmente volevi che occupasse l'intera larghezza e altezza del suo genitore.

 .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
Una figura in cui il video non copre lo sfondo dell'eroe
Il valore object-fit predefinito per l'elemento video è contain . Come puoi vedere qui, il video non copre lo sfondo dell'eroe, anche se ha position: absolute , width: 100% e height: 100% . (Grande anteprima)

Per fare in modo che copra completamente la larghezza e l'altezza del suo genitore, dobbiamo sovrascrivere il valore object-fit predefinito:

 .hero__video { /* other styles */ object-fit: cover; }
Una figura in cui il video copre l'intera larghezza e altezza del suo genitore.
Ora il video copre l'intera larghezza e altezza del suo genitore. (Grande anteprima)

Conclusione

Come abbiamo visto, sia object-fit che background-size sono molto utili per gestire diverse proporzioni dell'immagine. Non sempre avremo il controllo sull'impostazione delle dimensioni perfette per ogni immagine, ed è qui che brillano queste due funzionalità CSS.

Un promemoria amichevole sulle implicazioni per l'accessibilità della scelta tra un elemento img e uno sfondo CSS: se l'immagine è puramente decorativa, scegli uno sfondo CSS. Altrimenti, un img è più adatto.

Spero che tu abbia trovato utile questo articolo. Grazie per aver letto.