Propriété CSS aspect-ratio

Propriété CSS qui permet de maintenir l'espacement dans les mises en page responsives.

Navigateurs pris en charge

  • Chrome : 88.
  • Edge: 88
  • Firefox: 89
  • Safari: 15.

Source

Le format est généralement exprimé sous la forme de deux entiers et d'un deux-points dans les dimensions suivantes : largeur:hauteur ou x:y. Les formats les plus courants pour la photographie sont 4:3 et 3:2, tandis que les vidéos et les appareils photo grand public plus récents ont tendance à avoir un format 16:9.

Deux images au même format. L'une mesure 634 x 951 px, tandis que l'autre mesure 200 x 300 px. Les deux ont un format 2:3.
Deux images au même format. L'une mesure 634 x 951 px, tandis que l'autre mesure 200 x 300 px. Les deux ont un format 2:3.

Avec l'avènement du responsive design, le maintien du format est devenu de plus en plus important pour les développeurs Web, en particulier lorsque les dimensions des images diffèrent et que les tailles des éléments changent en fonction de l'espace disponible.

Voici quelques exemples de cas où il est important de conserver le format :

  • Créer des iFrames responsives, où elles représentent 100 % de la largeur d'un parent, et la hauteur doit rester un format de fenêtre d'affichage spécifique
  • Créer des conteneurs d'espace réservé intrinsèques pour les images, les vidéos et les éléments intégrés afin d'éviter la redisposition lorsque les éléments se chargent et prennent de la place
  • Créer un espace uniforme et responsif pour les visualisations de données interactives ou les animations SVG
  • Créer un espace uniforme et responsif pour les composants multi-éléments tels que les fiches ou les dates du calendrier
  • Créer un espace responsif et uniforme pour plusieurs images de différentes dimensions (peut être utilisé avec object-fit)

Ajustement des objets

Définir un format nous aide à dimensionner les contenus multimédias dans un contexte responsif. Un autre outil de ce bucket est la propriété object-fit, qui permet aux utilisateurs de décrire comment un objet (tel qu'une image) dans un bloc doit remplir ce bloc:

Visualisation de la démonstration de l'ajustement des objets
Présentation de différentes valeurs object-fit. Consultez la démonstration sur Codepen.

Les valeurs initial et fill réajustent l'image pour qu'elle remplisse l'espace. Dans notre exemple, l'image est écrasée et floue, car elle réajuste les pixels. Pas idéal. object-fit: cover utilise la plus petite dimension de l'image pour remplir l'espace et recadrer l'image pour qu'elle y tienne en fonction de cette dimension. Elle effectue un zoom avant sur sa limite la plus basse. object-fit: contain garantit que l'intégralité de l'image est toujours visible, ce qui est l'opposé de cover, qui prend la taille de la plus grande limite (dans notre exemple ci-dessus, il s'agit de la largeur) et redimensionne l'image pour conserver son format intrinsèque tout en s'adaptant à l'espace. Le cas object-fit: none affiche l'image recadrée au centre (position d'objet par défaut) à sa taille naturelle.

object-fit: cover fonctionne dans la plupart des situations pour garantir une interface uniforme lors du traitement d'images de dimensions variables. Cependant, vous perdez des informations de cette manière (l'image est recadrée à ses bords les plus longs).

Si ces détails sont importants (par exemple, lorsque vous travaillez avec un flat lay de produits de beauté), il n'est pas acceptable de recadrer du contenu important. Le scénario idéal serait donc d'utiliser des images responsives de différentes tailles qui s'adaptent à l'espace de l'interface utilisateur sans être recadrées.

L'ancien hack : conserver les proportions avec padding-top

Utilisation de padding-top pour définir un format 1:1 sur les images d'aperçu des posts dans un carrousel.
Utilisation de padding-top pour définir un format 1:1 sur les images d'aperçu des posts dans un carrousel.

Pour les rendre plus responsifs, nous pouvons utiliser le format. Cela nous permet de définir une taille de format spécifique et de baser le reste du contenu multimédia sur un axe individuel (hauteur ou largeur).

Une solution multinavigateur actuellement largement acceptée pour maintenir le format en fonction de la largeur d'une image est appelée "Padding-Top Hack". Cette solution nécessite un conteneur parent et un conteneur enfant placé de manière absolue. On calcule ensuite le format sous la forme d'un pourcentage à définir comme padding-top. Exemple :

  • Format 1:1 = 1 / 1 = 1 = padding-top: 100%
  • Format 4:3 = 3 / 4 = 0,75 = padding-top: 75%
  • Format 3:2 = 2 / 3 = 0,66666 = padding-top: 66.67%
  • Format 16:9 = 9 / 16 = 0,5625 = padding-top: 56.25%

Maintenant que nous avons identifié la valeur du format, nous pouvons l'appliquer à notre conteneur parent. Prenons l'exemple suivant :

<div class="container">
  <img class="media" src="..." alt="...">
</div>

Nous pourrions ensuite écrire le code CSS suivant :

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

Maintien des proportions avec aspect-ratio

Utilisation de &quot;aspect-ratio&quot; pour définir un format 1:1 sur les images d&#39;aperçu des posts dans un carrousel.
Utilisation de aspect-ratio pour définir un format 1:1 sur les images d'aperçu des posts dans un carrousel.

Malheureusement, le calcul de ces valeurs padding-top n'est pas très intuitif et nécessite des frais généraux et un positionnement supplémentaires. Avec la nouvelle propriété CSS aspect-ratio intrinsèque, le langage permettant de maintenir les formats est beaucoup plus clair.

Avec le même balisage, nous pouvons remplacer padding-top: 56.25% par aspect-ratio: 16 / 9, en définissant aspect-ratio sur un ratio spécifié de width/height.

Utiliser la marge intérieure supérieure
.container {
  width: 100%;
  padding-top: 56.25%;
}
Utiliser aspect-ratio
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

L'utilisation de aspect-ratio au lieu de padding-top est beaucoup plus claire et ne remanie pas la propriété de marge intérieure pour effectuer une action en dehors de son champ d'application habituel.

Cette nouvelle propriété permet également de définir le format sur auto, où "les éléments remplacés par un format intrinsèque utilisent ce format. Sinon, la zone n'a pas de format préféré". Si auto et <ratio> sont spécifiés ensemble, le format préféré est le format spécifié de width divisé par height, sauf s'il s'agit d'un élément remplacé avec un format intrinsèque, auquel cas ce format est utilisé à la place.

Exemple: cohérence dans une grille

Cela fonctionne très bien avec les mécanismes de mise en page CSS tels que la grille CSS et Flexbox. Imaginez une liste avec des enfants dont vous souhaitez conserver le format 1:1, par exemple une grille d'icônes de soutien:

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
Images dans une grille avec leur élément parent dans différents formats. Voir la démo sur Codepen

Exemple: Empêcher le décalage de mise en page

aspect-ratio présente également une autre excellente fonctionnalité : il peut créer un espace réservé pour éviter le déplacement cumulé de la mise en page et améliorer les métriques Web Vitals. Dans ce premier exemple, le chargement d'un élément à partir d'une API telle que Unsplash crée un décalage de mise en page lorsque le contenu multimédia a fini de se charger.

Vidéo d'un décalage de mise en page cumulatif qui se produit lorsqu'aucun format n'est défini sur un élément chargé. Cette vidéo est enregistrée avec un réseau 3G émulé.

En revanche, l'utilisation de aspect-ratio crée un espace réservé pour éviter ce décalage de mise en page :

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
La vidéo avec un format défini est définie sur un composant chargé. Cette vidéo est enregistrée avec un réseau 3G émulé. Voir la démonstration sur Codepen

Conseil supplémentaire : Attributs image pour le format

Vous pouvez également définir le format d'une image à l'aide des attributs image. Si vous connaissez les dimensions de l'image à l'avance, il est recommandé de les définir sur width et height.

Dans notre exemple ci-dessus, sachant que les dimensions sont de 800 x 600 pixels, la balise d'image se présente comme suit : <img src="image.jpg" alt="..." width="800" height="600">. Si l'image envoyée a le même format, mais pas nécessairement les valeurs exactes en pixels, nous pouvons toujours utiliser les valeurs d'attribut d'image pour définir le format, combinées à un style de width: 100% afin que l'image occupe l'espace approprié. Le tout se présente comme suit :

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

En fin de compte, l'effet est identique à la définition de aspect-ratio sur l'image via CSS, et le décalage de mise en page cumulatif est évité (voir la démonstration sur Codepen).

Conclusion

Avec la nouvelle propriété CSS aspect-ratio, lancée dans plusieurs navigateurs modernes, il est un peu plus simple de maintenir les formats appropriés dans vos conteneurs de contenu multimédia et de mise en page.

Photos d'Amy Shamblen et de Lionel Gustave via Unsplash.