Frontend

Immagini, multimedia e filtri in CSS

Autore

Manuel Ricci

In HTML <img /> e <video> sono due tag di tipo sostitutivo. Ciò significa che con CSS non abbiamo la possibilità di modificarne il layout interno, ma solo la loro posizione, ma, fortunatamente, non finisce qui.

In realtà CSS ci mette a disposizione varie proprietà che ci permettono di ottenere il massimo da questi elementi e abbiamo anche la possibilità di inserire delle immagini di sfondo direttamente dal foglio di stile.

In questo approfondimento vediamo alcune proprietà utili per poter modificare il modo in cui le immagini vengono presentate e come inserirle direttamente da CSS.

Modifiche le dimensioni delle immagini in CSS

In HTML abbiamo a disposizione due attributi, width e height che ci permettono di definire lo spazio d'ingombro dell’immagine.

Con CSS abbiamo la possibilità di definire larghezza e altezza allo stesso modo con delle proprietà omonime. Averle a disposizione in CSS non significa che non dobbiamo usarle in HTML.

Definire una larghezza ed un'altezza fissa da HTML permette di evitare il Cumulative Layout Shift, una metrica che Google usa per valutare algoritmicamente la user experience del sito web.

Le immagini di default tendono comunque a fuori uscire dall’elemento genitore, per evitare questo comportamento è sempre buona cosa impostare la proprietà max-width al 100%. In questo modo l’immagine occuperà sempre il massimo spazio consentito dal genitore.

1img {
2   max-width: 100%;
3}

Ovviamente, anche se scrivo di immagini, gli stessi concetti valgono per video e iframe.

Sistemare l’immagine rispetto al genitore

Abbastanza recenti rispetto ad altre proprietà che vedremo successivamente, CSS mette a disposizione object-fit e object-position.

Cosa risolvono esattamente? Tempo fa quando volevamo fare in modo che un'immagine si adattasse al proprio contenitore optavamo per usare background-image, con background-image però non abbiamo tutta una serie di comodità offerte da HTML, come ad esempio il lazy loading.

Di conseguenza, come vedremo più avanti, le proprietà background-* ci permettono di modificare la dimensione dello sfondo e la posizione. object-fit e object-position ci danno esattamente gli stessi controlli offerti da background-size e background-position, ma controllando un tag <img /> al posto di un’immagine di sfondo.

Nello specifico:

  • object-fit: imposta il modo in cui un'immagine o un video dovrebbe essere ridimensionati rispetto al contenitore
  • object-position: imposta l’allineamento di un elemento sostituito (immagine o video) rispetto al contenitore
1img {
2   object-fit: contain;
3}

I valori consentiti di object-fit sono:

  • contain: il contenuto viene scalato per mantenere il proprio aspect ratio rientrando però nei “confini” dell’elemento contenitore.
  • cover: il contenuto mantiene il suo aspect ratio riempiendo l’elemento contenitore. Se l’aspect ratio fosse più grande del contenitore, l’immagine verrà ritagliato per adattarlo.
  • fill: simile a cover con la differenza che l’elemento non viene ritagliato, ma viene stretchato per rientrare nei “confini” dell’elemento contenitore
  • none: nessun azione viene eseguita
  • scale-down: il contenuto si comporta come se none o contain fossero impostati a seconda di quale delle due opzioni risulterebbe in una dimensione dell’oggetto più piccola.

Mentre per quanto riguarda object-position l’unico valore atteso è un data type <position>.

1img {
2   object-position: 50% 50%;
3}
4
5img {
6   object-position: right top;
7}

Modificare l’aspect ratio

La proprietà aspect-ratio permette di definire il rapporto larghezza-altezza di un elemento (non solo immagini e video).

aspect-ratio è una proprietà estremamente comoda, soprattutto quando si vogliono rendere responsive gli iframe. Il problema che ci siamo sempre posti quando c’era da renderli responsive era che usare semplicemente width: 100% sugli schermi più piccoli scalava fin troppo, rendendo l’iframe praticamente inguardabile.

Di conseguenza per renderlo responsive si usava questa tecnica:

1<div class="container">
2  <iframe class="responsive-iframe" src="https://www.youtube.com/embed/7M2w1IrdJ9o"></iframe>
3</div>
1.container {
2  position: relative;
3  overflow: hidden;
4  width: 100%;
5  padding-top: 56.25%;
6}
7
8.responsive-iframe {
9  position: absolute;
10  top: 0;
11  left: 0;
12  bottom: 0;
13  right: 0;
14  width: 100%;
15  height: 100%;
16}

In soldoni cosa c’è scritto? Tralasciando il superfluo che ci interessa relativamente, la peculiarità di questo CSS sta nel padding-top che è impostato ad una valore specifico (9 diviso per 16 = 0.5625) in questo modo il nostro .container è in 16:9. Poi .responsive-iframe viene posizionato rispetto al contenitore estendendolo per il 100% della larghezza e dell’altezza dello stesso.

Con aspect-ratio la soluzione è semplicissima:

1<iframe class="responsive-iframe" src="https://www.youtube.com/embed/7M2w1IrdJ9o"></iframe>
1iframe {
2   aspect-ratio: 16 / 9;
3   height: 100%;
4   width: 100%;
5}

Fine. Fantastico vero?

Filtri delle immagini

Con CSS si possono utilizzare dei filtri che applicano degli effetti grafici come sfocatura o filtro colore ad un elemento.

I filtri disponibili sono le funzioni:

  • blur()
  • brightness()
  • contrast()
  • drop-shadow()
  • grayscale()
  • hue-rotate()
  • invert()
  • opacity()
  • saturate()
  • sepia()

Si può anche utilizzare la funzione url() per definire un filtro SVG

1img {
2   filter: drop-shadow(16px 16px 10px black);
3}

Sempre a tema filtri

Esiste un’altra proprietà per i filtri che è backdrop-filter, la quale permette di applicare gli stessi effetti grafici visti in precedenza, ma all’area dietro all’elemento.

Questa proprietà è alla base di effetti come ad esempio il glassmorfismo.

1.glass {
2   background: rgba(255, 255, 255, 0.2);
3   border-radius: 16px;
4   box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
5   backdrop-filter: blur(5px);
6   border: 1px solid rgba(255, 255, 255, 0.3);
7}

Maschere con clip-path

clip-path crea una sorta di maschera di ritaglio che mostra solo la parte che si desidera mostrare e nasconde la parte ritagliata.

1<div>
2      <img src="immagine.jpg" width="150" />
3     Lorem ipsum dolor sit amet consectetur, adipisicing elit. Totam eos officia doloremque non, officiis deleniti. Quod perspiciatis, sed quaerat officia asperiores nemo, eaque fugit culpa tempora id nihil, recusandae fuga.
4    </div>
1img {
2   clip-path: polygon(50% 0px, 100% 50%, 50% 100%, 0px 50%);
3}

Impostare un’immagine di sfondo

Come già visto in precedenza attraverso le proprietà background-image abbiamo la possibilità di inserire un’immagine attraverso l’uso della funzione url().

Questa funzione si può usare anche in altre proprietà, ma l’uso più frequente è proprio con background-image.

background-* ha una serie di proprietà specifiche ci permettono di controllare l’immagine, nello specifico:

  • attachment: definisce come un’immagine di sfondo si comporta quando si scrolla la pagina (fissa o a scorrimento)
  • blend-mode: come l’immagine di sfondo (o il colore) si mischia con gli elementi sottostanti
  • clip: definisce come lo sfondo si estende nel contenitore in base a border, padding o content box.
  • color: definisce un colore di sfondo, impostabile anche con l’uso di image perché nel caso l’immagine non caricasse verrà mostrato il colore di sfondo come fallback/
  • image: definisce un’immagine di sfondo
  • origin: definisce il punto di partenza dalla quale viene mostrata l’immagine di sfondo, come per clip border, padding e content box
  • position: definisce il posizionamento dell’immagine di sfondo e accetta come valore il data type <position>
  • repeat: definisce come e se si ripete l’immagine di sfondo.
  • size: uguale ad object-fit per valori, l’immagine si comporterà come spiegato precedentemente.

Caricamento...

Diventiamo amici di penna? ✒️

Iscriviti alla newsletter per ricevere una mail ogni paio di settimane con le ultime novità, gli ultimi approfondimenti e gli ultimi corsi gratuiti puubblicati. Ogni tanto potrei scrivere qualcosa di commerciale, ma solo se mi autorizzi, altrimenti non ti disturberò oltre.

Se non ti piace la newsletter ti ricordo la community su Discord, dove puoi chiedere aiuto, fare domande e condividere le tue esperienze (ma soprattutto scambiare due meme con me). Ti aspetto!

Ho in previsione di mandarti una newsletter ogni due settimane e una commerciale quando capita.