Aspect-ratio: la nuova proprietà css

Quante volte vi è capitato di dover realizzare un mockup responsive e mantenere l’aspect ratio per le immagini sembrava una cosa alquanto ostica? Finalmente è disponibile la soluzione!

Ebbene sì, le proporzioni, ovvero il rapporto esistente tra le due dimensioni larghezza e lunghezza (x:y), principalmente di immagini e video, sono per chi si occupa di frontend, da sempre una questione spinosa.

Nel tempo sono state sperimentate diverse soluzioni per questo problema, come ad esempio l’utilizzo del padding come hack o altri metodi esposti qui su CSS Tricks. Ad oggi, però, abbiamo la fortuna di poter seguire una nuova strada, usando la proprietà css aspect-ratio, introdotta dalla specifica CSS Sizing 4.
Con la proprietà CSS aspect-ratio, il mantenimento delle proporzioni corrette dei contenuti multimediali e di layout diventa un po' più semplice.


Vediamo come funziona questa proprietà e come si usa.
Le caratteristiche di default:

/* Valori di default */
aspect-ratio: auto; /* default */

/* Valori della ratio */
aspect-ratio: 1 / 1; /* larghezza e altezza sono uguali */
aspect-ratio: 2 / 1; /* la larghezza è due volte l’altezza*/
aspect-ratio: 1 / 2; /* l’altezza è due volte la larghezza */
aspect-ratio: 16 / 9 /* Proporzioni standard per un video */
aspect-ratio: auto 4 / 3; /* larghezza:altezza, a meno che un elemento non venga sostituito */

/* Valori Globali */
aspect-ratio: inherit;
aspect-ratio: initial;
aspect-ratio: unset;

Sintassi formale

auto | <ratio>


<auto>: il valore predefinito, specifica che l'elemento non ha proporzioni definite e dovrebbe ridimensionarsi come farebbe normalmente.
<ratio>: il rapporto preferito viene specificato da due valori numerici positivi separati da una barra (/) con o senza spazio intorno, che agiscono sulla larghezza e sull'altezza dell'elemento. Nel caso venga specificato un solo valore, il secondo viene considerato uguale a 1. Le proporzioni preferite vengono applicate al contenitore per il quale è stato specificato il box-sizing.

Come si usa

Quello che prima veniva fatto con il padding-top hack adesso diviene più semplice con l’aspect-ratio.

L'uso di aspect-ratio invece di padding-top è molto più chiaro e non modifica la proprietà padding per forzare un comportamento innaturale.
Se vengono specificati insieme sia <auto> che <ratio>, la aspect-ratio preferita equivale al rapporto specificato tra la larghezza diviso l’altezza, a meno che non si tratti di un elemento sostituito con una aspect ratio intrinseca, nel qual caso viene utilizzato quella ratio.

Ecco alcuni esempi in cui la proprietà aspect-ratio diventa particolarmente utile.

Responsive iframe

Un caso d'uso molto comune è quando si vuole incorporare un iframe per visualizzare un video da un sito esterno come YouTube. In questo caso, se impostiamo la larghezza al 100% e l'altezza come misura predefinita, il video verrà deformato.

Per avere un iframe reattivo che mantenga le sue proporzioni possiamo impostare quanto segue:

iframe {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}

Se l'iframe ha attributi di larghezza ed altezza impostati in questo modo:

<iframe width="800" height="600" src="https://example.com"></iframe>

possiamo impostare automaticamente le proporzioni così:

img {
	width: 100%;
	aspect-ratio:8/6;
}  

Hero images

L'impostazione di un'immagine di background su un elemento non ha alcun effetto sulla dimensione di quell'elemento. Quindi, per creare un'immagine hero, se l'immagine è di background, è necessario impostare un'altezza, cosa che crea molti problemi nel responsive.

La proprietà aspect-ratio ci viene in aiuto per ottenere un hero che conservi le proporzioni della sua immagine di background:

.hero {
  aspect-ratio: 4 / 3;
  background: url(background.png);
}

Grid layout

Immaginiamo, in un flexbox o in un layout a griglia con meccanismo di riempimento automatico, di poter volere che gli elementi rimangano quadrati, ma la larghezza e l'altezza degli elementi debbano poter ridursi o crescere in base al loro contenuto o alle dimensioni dei genitori e, di conseguenza, è molto probabile che gli elementi non non restino quadrati.

L'impostazione delle proporzioni su 1/1 modifica l'altezza in modo dinamico, mentre la larghezza dell'elemento si ridimensiona:

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}

.grid-item {
  aspect-ratio: 1 / 1;
}

e ancora, l’aspect-ratio ci viene in aiuto nel:

  • creare uno spazio uniforme e responsive per visualizzazioni di dati interattivi o animazioni SVG;
  • progettare uno spazio uniforme e reattivo per componenti multi-elemento come card o elementi di un calendario;
  • creare contenitori responsive per più immagini di dimensioni variabili.

Casi in cui non funziona

Ma ci sono anche situazioni in cui l’aspect-ratio non funziona, in quanto sovrascritto da altre proprietà o ignorate.
Ad esempio:

  • Quando sull'elemento sono dichiarate sia la larghezza che l'altezza.
    Se l'elemento ha già sia una larghezza che un'altezza, queste vengono utilizzate al posto delle proporzioni. Se l'utilizzo della larghezza o dell'altezza impone alle proporzioni di utilizzare quel valore nel calcolo, ne consegue logicamente che l'utilizzo di entrambe sovrascriverà completamente le proporzioni poiché entrambi i valori sono già forniti e impostati.
  • Quando il contenuto rompe il rapporto di proporzione.
    In poche parole, se si dispone di un elemento con proporzioni e il contenuto è così lungo da forzare l'espansione dell'elemento, l'elemento si espanderà. E se l'elemento si espande, le sue dimensioni cambiano e, quindi, non valgono più le proporzioni. Questo è il motivo per cui la specifica dice che la proprietà imposta le proporzioni "preferite". È preferito, ma non prescritto. Vogliamo ovviare a questo inconveniente? Impostiamo l’altezza minima a 0 sull'elemento. Questo consentirà al contenuto di superare le proporzioni preferite invece di espanderlo (esempio)
  • Con proprietà min-* e max-*:
    Quando il contenuto supera le dimensioni del riquadro, le proporzioni vengono effettivamente eliminate perché il riquadro si espande con il contenuto. Possiamo sovrascriverlo con min-width: 0.
    Questo perché tutte le proprietà min-* e max-* in genere combattono larghezza e altezza per la supremazia nella guerra sui calcoli del Box Model. La stessa cosa vale per l'altezza minima, la larghezza massima e l'altezza massima. Riassumendo: se impostiamo una delle due proprietà min-* o max-* sullo stesso elemento delle proporzioni e queste "vincono" su larghezza o altezza, allora esse sovrascriveranno le proporzioni.

Compatibilità cross-browser


Come si può verificare sul portale caniuse.com ci sono alcuni browser che non interpretano questa proprietà css.
can-i-use-min.png

Con i browser più vecchi, però, si può optare per la tecnica del padding, aggiungendo agli pseudo elementi il CSS @supports. Ad esempio:

.element {
  aspect-ratio: 1 / 1;
}

@supports not (aspect-ratio: 1 / 1) {
  .element::before {
    float: left;
    padding-top: 100%;
    content: "";
  }

  .element::after {
    display: block;
    content: "";
    clear: both;
  }
}



Link utili

https://www.w3schools.com/css/css3_box-sizing.asp

https://web.dev/aspect-ratio

https://css-tricks.com/almanac/properties/a/aspect-ratio

Autoreadmin