Twitter
Partagez cette démonstration : Twitter

Le format d'image en CSS

Dernière mise à jour : juin 2022

Introduction

Dans la conception web, la notion de format d'image réprésente la manière dont une image doit être redimensionnée proportionnellement à sa largeur ainsi que sa hauteur.

Le format d'image est le plus souvent exprimé par deux nombres entiers (exemple : 4:3), la largeur en premier puis la hauteur. Les rapports d'aspect les plus courants pour la photographie sont 4:3 et 3:2, tandis que la vidéo et les appareils photo les plus récents ont un rapport d'aspect de 16:9.


Le hack css avec la propriété padding

Il s'agit d'une vieille méthode pour conserver un rapport d'aspect qui, avec l'arrivée de la propriété aspect-ratio, dont le support est désormais étendu, ne s'avère plus utile. Il faut avouer que cette solution n'est ni naturelle ni intuitive.

Lorsqu'un élément possède un pourcentage de rembourrage vertical, il est alors basé sur la largeur de son élément parent.

Pour exemple :

  • Le format d'image 16:9 équivaut à 9 / 16 * 100% = 56.25%
  • Le format d'image 4:3 équivaut à 3 / 4 * 100% = 75%
  • Le format d'image 3:2 équivaut à 2 / 3 * 100% = 66.66%
  • Le format d'image 1:1 équivaut à 1 / 1 * 100% = 100%

Testez par vous-même :

Ci-dessous, nous avons un dégradé dont nous voulons garder un rapport d'aspect. Nous connaisons la largeur de l'élément parent (768px). Nous souhaitons obtenir un format 16:9 dont le pourcentage à utiliser pour le rembourrage est de 56.25%.



<div class=cadre-gradient>	
<div class="gradient">
</div>
</div>




.cadre-gradient{

width: 40vw;

}

.gradient {

background-image: linear-gradient(
  45deg,
  hsl(240deg 100% 20%) 0%,
  hsl(289deg 100% 21%) 11%,
  hsl(315deg 100% 27%) 22%,
  hsl(329deg 100% 36%) 33%,
  hsl(337deg 100% 43%) 44%,
  hsl(357deg 91% 59%) 56%,
  hsl(17deg 100% 59%) 67%,
  hsl(34deg 100% 53%) 78%,
  hsl(45deg 100% 50%) 89%,
  hsl(55deg 100% 50%) 100%
);
padding-top: 56.25%; /*16:9*/
		
}



Le cas du débordement

Dans l'exemple ci-dessous, nous avons défini un format d'image fixe. Le problème est simple. Si nous ajoutons trop de contenu à l'intérieur de notre élément, ledit contenu va immanquablement dépasser de son conteneur lorsque nous allons passer sur un écran plus petit.

Nous pourrions alors ajouter simplement la propriété overflow pour ainsi faire apparaître une barre de défilement et, de fait, englober tout le contenu, comme ceci :

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Mais, vous l'aurez compris, l'objectif est que le conteneur suive le flux du contenu. Une solution existe là-aussi. Il s'agit d'utiliser les pseudo-éléments ::before et ::after :



.debordement{

  padding: 1rem;
  background-color: hsla(248, 78%, 62%, 0.6);
}

.debordement::before {

  content: "";
  padding-top: 56.25%;
  float: left;
  
}

.debordement::after {

  clear: left;
  content: " ";
  display: table;
  
	}
	
.debordement p{

font-size: 3rem;

}	
	


Changer les proportions d'une image

Ci-dessous, nous affichons une image au format 3:2.

Reprenons cette image pour changer de format et opter pour le 16:9.

Nous remarquons que l'image est allongée. Pour éviter que l'image ne soit écrasée par le nouveau format, nous ajoutons la propriété object-fit associée à la valeur cover de manière à occuper tout l'espace. Je vous invite à vous renseigner sur les propriétés d'images.



<div class="aspect-ratio--16-9">
<img src="image.jpg" alt>
</div>


Dans le code CSS ci-dessous, nous utilisons une méthode plus moderne avec les propriétés personnalisées. Le principe reste le même. L'intérêt d'appliquer les propriétés personnalisées interviendra dans le cas où vous aurez plusieurs formats d'image à déclarer.



.aspect-ratio--16-9 {

--aspect-ratio: 16/9;
position: relative;
/*padding-top: 56.25%;*/
padding-top: calc(100%/(var(--aspect-ratio)));
		
}

.aspect-ratio--16-9 > * {

position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;

}	
	


Autre exemple avec trois colonnes contenant deux images au format 3:2 et une au format 16:9. L'image au format 16:9 est redéfinie au format 3:2 et conserve les mêmes proportions que les autres images grâce à la propriété vue plus haut, à savoir object-fit.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.



<div class=cadre-ratio>	

<div class="colonne--3-2">
<div class="cadre-colonne--3-2">
<img src="image--3-2.jpg" alt>
</div>

...

</div>

<div class="colonne--3-2">
<div class="cadre-colonne--3-2">
<img src="image--3-2.jpg" alt>
</div>

...

</div>

<div class="colonne--3-2">
<div class="cadre-colonne--3-2">
<img src="image--3-2.jpg" alt>
</div>

...

</div>


</div>




.cadre-ratio{

display: grid;
grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr));
gap: 2rem;


	
	}
	
.colonne--3-2{
	
background-color: white;
overflow: hidden;
border-radius: 0.5rem;
box-shadow: 0.05rem 0.1rem 0.3rem -0.03rem rgba(0, 0, 0, 0.45);
	
}
		
.cadre-colonne--3-2 {

position: relative;
padding-top: 66.66%;

}

.cadre-colonne--3-2 img {

position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;

}
	
.contenu-colonne--3-2{

padding:1rem;

}

Un exemple où la méthode avec le padding hack s'est avérée très utile se portait sur les diaporamas, sliders et autres carrousels. Comme les images se superposent en positionnement absolu, cette solution permettait de rendre la galerie responsive.

Vous pouvez retrouver cet exemple avec le code sur cette page du blog.

Le cas de l'image d'arrière-plan

Définir une image comme arrière-plan n'est pas une bonne pratique pour afficher une image. En effet, celle-ci ne sera pas reconnue par les technologies d'assistance. L'image d'arrière-plan ne doit être définie qu'à des fins décoratives. On veillera donc à ajouter l'attribut aria-label en lieu et place de l'attribut alt.

Comme il s'agit d'une image de fond, nous n'allons pas utiliser la propriété object-fit propre aux images, mais la propriété background-size afin de définir le type de remplissage.



<div class="cadre-aspect-ratio-background">
<div aria-label="exemple aspect ratio image de fond" class="aspect-ratio-background">
</div>
</div>





.cadre-aspect-ratio-background{

margin:auto;
max-width: 800px;

}	

.aspect-ratio-background {

padding-top: 56.25%; /*16:9*/
background: url('image-fond.jpg') no-repeat center/cover;

}	



Reprenons l'exemple avec trois colonnes. Cette fois-ci les images sont des images d'arrière-plan et se présentent au format 16:9.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.



<div class=cadre-ratio--16-9-background>	

<div class="ratio--16-9-background">
<div class="ratio--16-9-background-img" aria-label="..." style="background-image: url(image.jpg)"></div>

...

</div>

<div class="ratio--16-9-background">
<div class="ratio--16-9-background-img" aria-label="..." style="background-image: url(image.jpg)"></div>


...

</div>


<div class="ratio--16-9-background">
<div class="ratio--16-9-background-img" aria-label="..." style="background-image: url(image.jpg)"></div>


...

</div>


</div>





.cadre-ratio--16-9-background {
  display: grid;
  grid-gap: 2rem;
  justify-content: center;
  grid-template-columns: repeat(auto-fit, minmax(30ch, 1fr));
  
}

.ratio--16-9-background {

  border: 1px solid #c9c9c9;
  border-radius: 7px;
  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  
}



.ratio--16-9-background-img {

 background-size: cover;
 background-position: center;
 padding-bottom: 56.25%;/*16/9*/
 
}




Les éléments remplacés

Un élément remplacé est un élément dont le contenu est en dehors de la portée du modèle de formatage CSS, comme une image, une vidéo ou encore un document intégré (iframe).

Un élément remplacé est différent des autres boîtes en CSS. En effet, celui-ci possède des dimensions et un comportement propres. On dit que les éléments remplacés ont un rapport d'aspect intrinsèque, car ils ont des dimensions.

Comme nous avons pu le voir, il est possible de définir une proportion sur un élément qui possède un rapport d'aspect intrinsèque. Dans ce cas, la déclaration du ratio remplacera le rapport d'aspect intrinsèque.

	

<div class="cadre-video">
<video src="video.mp4" controls>
</div>
</div>





.cadre-video {

  position: relative;
  padding-top: 56.25%;/*16:9*/
}

.cadre-video>* {
  position: absolute;
  top: 0;
  left:0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}



	

<div class="cadre-iframe">
<iframe src=""></iframe>
</div>





.cadre-iframe {

  position: relative;
  padding-top: 56.25%;/*16:9*/
}

.cadre-iframe>*{
  position: absolute;
  top: 0;
  left:0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}




La propriété aspect-ratio

Contrairement au padding hack, avec cette propriété, nous n'avons plus besoin d'un élément parent en se basant sur sa largeur pour englober le contenu dont nous tenons à garder les proportions. C'est beaucoup plus simple et cela allège le code.

Testez par vous-même :

En effet, il suffit de déclarer une largeur ou une hauteur à un élément et de définir un rapport d'aspect. C'est tout !

16:9



width: 20vw;
aspect-ratio: 16 / 9; /* 20vw / 16 * 9 = Hauteur 11.25vw */


Par contre, si vous déclarez une largeur ainsi qu'une hauteur à un élément, la propriété aspect-ratio n'aura aucun effet.

Dans le cas où vous avez un élément à l'intérieur d'un parent auquel vous avez défini une hauteur, il suffit de déclarer la propriété aspect-ratio sur l'élément enfant.



.parent-aspect {

  height: 200px;
  
}

.parent-aspect div {

background: #6753ea;
aspect-ratio: 1 / 1;

}


Le cas du débordement

Vous allez voir que la mise en place est beaucoup plus rapide et cohérente qu'avec le padding hack. En retirant la hauteur fixe, la taille de l'élément va s'adapter grâce à la propriété aspect-ratio.

Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.



.element{

width: min(200px, 100%);
aspect-ratio: 2 / 1;

}



Changer les proportions d'une image

Nous retrouvons notre image au format 3:2 et nous changeons son format pour du 16:9.

Encore une fois, avec la propriété aspect-ratio, c'est beaucoup plus simple :



img{

display: block;
width:  100%;
aspect-ratio: 16/9;
object-fit: cover

}



Une nouvelle fois, reprenons l'exemple avec nos trois colonnes en utilisant la propriété aspect-ratio. Vous pouvons mettre des images de tailles différentes. Elle auront toutes les mêmes proportions (ici le format est 3:2).

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Titre

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius orci sit amet massa placerat, vitae malesuada turpis suscipit. Ut interdum scelerisque sodales.

Le cas de l'image d'arrière-plan

Rien de mieux pour réaliser un header (entête) sur votre site/blog. En quelques déclarations, vous obtenez un résultat très satisfaisant et responsive.

Bienvenue sur mon blog



.entete-aspect {

aspect-ratio: 16 / 9; 
display: flex;
align-items: center;
justify-content: center;
background: url(image.jpg) no-repeat center/cover, linear-gradient(violet, #6753ea);
background-blend-mode: overlay;

}

.entete-aspect h1{

font-size: 4vw;
color: white

}



Les éléments remplacés



<iframe src="" width="560" height="315" style="--aspect-ratio: 560 / 315"></iframe>
//ici on choisit d'écrire la largeur divisée par la hauteur ce qui revient à écrire --aspect-ratio:16/9 




iframe {

 aspect-ratio: var(--aspect-ratio); 
  width: 100%;
  height: auto;
}


Le fallback, la solution de repli

Comme nous avons pu le voir, le padding hack ne devrait pas être utilisé. Mais force est de constater qu'il fonctionne très bien et que le support est très bon. Si vous souhaitez mettre en place une solution de repli, celle-ci devrait vous convenir :



.class {
  --aspect-ratio: 16/9;
  padding-top: calc((1 / (var(--aspect-ratio))) * 100%);
}

@supports (aspect-ratio: 1) {
  .class {
    aspect-ratio: var(--aspect-ratio);
    padding-top: initial;/*on annule le padding*/
  }
}




Vous rencontrez un problème avec cet article ?

Vous avez remarqué une faute, un oubli, un lien mort ? Vous ne comprenez pas un point précis de l'article ? Vous pouvez me contacter par mail (contact@guyom-design.com) et je vous aiderai si je le peux.

haut page