Une plongée profonde dans l'ajustement d'objet et la taille d'arrière-plan en CSS

Publié: 2022-03-10
Résumé rapide ↬ Dans cet article, nous verrons comment fonctionnent object-fit et background-size , quand nous pouvons les utiliser et pourquoi, ainsi que des cas d'utilisation pratiques et des recommandations. Plongeons dedans.

Nous ne sommes pas toujours en mesure de charger des images de tailles différentes pour un élément HTML. Si nous utilisons une largeur et une hauteur qui ne sont pas proportionnelles au format de l'image, l'image peut être compressée ou étirée. Ce n'est pas bon, et cela peut être résolu soit avec object-fit pour un élément img , soit en utilisant background-size .

Tout d'abord, définissons le problème. Considérez la figure suivante :

Une belle photo et une image comprimée en comparaison
Une belle photo qui se comprime lorsqu'elle est utilisée dans un composant de carte. ( Grand aperçu )

Pourquoi cela arrive-t-il?

Une image aura un rapport d'aspect, et le navigateur remplira la boîte contenant cette image. Si le rapport d'aspect de l'image est différent de la largeur et de la hauteur spécifiées pour celle-ci, le résultat sera une image comprimée ou étirée.

Nous le voyons sur la figure suivante :

Une belle photo et une image étirée en comparaison
Le rapport d'aspect de l'image est différent de celui de la boîte contenante et l'image est étirée. ( Grand aperçu )

La solution

Nous n'avons pas toujours besoin d'ajouter une image de taille différente lorsque le rapport d'aspect de l'image ne s'aligne pas sur la largeur et la hauteur de l'élément contenant. Avant de plonger dans les solutions CSS, je veux vous montrer comment nous faisions cela dans les applications de retouche photo :

Exemple d'image avec les bords supérieur et inférieur recadrés dans un masque
Tout d'abord, nous centrions l'image verticalement, puis nous découpons un masque. Cela conserve le rapport d'aspect de l'image et l'empêche d'être comprimé. ( Grand aperçu )

Maintenant que nous comprenons comment cela fonctionne, voyons comment cela fonctionne dans le navigateur. ( Alerte spoiler : c'est plus facile ! )

object-fit CSS

La propriété object-fit définit comment le contenu d'un élément remplacé tel que img ou video doit être redimensionné pour s'adapter à son conteneur. La valeur par défaut pour object-fit est fill , ce qui peut entraîner la compression ou l'étirement d'une image.

Passons en revue les valeurs possibles.

Plus après saut! Continuez à lire ci-dessous ↓

Valeurs possibles pour object-fit

object-fit: contain

Dans ce cas, l'image sera redimensionnée pour s'adapter au format de son conteneur. Si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, il sera mis en boîte aux lettres.

ajustement à l'objet : contenir
Lorsque vous utilisez object-fit: contain , l'image sera soit en boîte aux lettres, soit redimensionnée en conséquence. ( Grand aperçu )

object-fit: cover

Ici, l'image sera également redimensionnée pour s'adapter au rapport d'aspect de son conteneur, et si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, alors elle sera coupée pour s'adapter.

conforme à l'objet : couverture
Lorsque vous utilisez object-fit: cover , l'image sera soit coupée pour s'adapter, soit redimensionnée en conséquence. ( Grand aperçu )

object-fit: fill

Avec cela, l'image sera redimensionnée pour s'adapter au rapport d'aspect de son conteneur, et si le rapport d'aspect de l'image ne correspond pas à celui du conteneur, elle sera soit comprimée, soit étirée. Nous ne voulons pas cela.

ajustement à l'objet : remplir
Lorsque vous utilisez object-fit: fill , l'image sera comprimée, étirée ou redimensionnée en conséquence. ( Grand aperçu )

object-fit: none

Dans ce cas, l'image ne sera pas du tout redimensionnée, ni étirée ni comprimée. Elle fonctionne comme la valeur de cover , mais elle ne respecte pas les proportions de son conteneur.

ajustement à l'objet : aucun
Lorsque vous utilisez object-fit: none , l'image ne sera pas redimensionnée si ses dimensions ne sont pas les mêmes. ( Grand aperçu )

Outre object-fit , nous avons également la propriété object-position , qui est responsable du positionnement d'une image dans son conteneur.

Valeurs possibles pour object-position

La propriété object-position fonctionne de la même manière que la propriété background-position de CSS :

position de l'objet centre, gauche, droite
La plupart du temps, la valeur par défaut est utilisée (c'est-à-dire `center` ou `50% 50%`). ( Grand aperçu )

Les mots-clés du top et du bottom fonctionnent également lorsque le rapport d'aspect de la boîte contenante est verticalement plus grand :

position de l'objet en haut et en bas
Comparaison object-position: top (gauche) et object-position: bottom (droite). ( Grand aperçu )

background-size CSS

Avec background-size , la première différence est que nous avons affaire à l'arrière-plan, pas à un élément HTML ( img ).

Valeurs possibles pour background-size

Les valeurs possibles pour background-size sont auto , contain et cover .

background-size: auto

Avec auto , l'image restera à sa taille par défaut :

taille d'arrière-plan : automatique
Gardez à l'esprit que la taille par défaut peut parfois donner une image floue (si elle est trop petite). ( Grand aperçu )

background-size: cover

Ici, l'image sera redimensionnée pour tenir dans le conteneur. Si les rapports d'aspect ne sont pas les mêmes, l'image sera masquée pour s'adapter.

taille de fond : couverture
Lorsque vous utilisez background-size: cover , assurez-vous de prendre en compte les proportions d'une image. ( Grand aperçu )

background-size: contain

Dans ce cas, l'image sera redimensionnée pour tenir dans le conteneur. Si les rapports d'aspect sont désactivés, l'image sera en format letterbox comme indiqué dans l'exemple suivant :

taille d'arrière-plan : contient
background-size: contain contains redimensionne l'image pour tenir dans le conteneur. ( Grand aperçu )

Quant à background-position , il est similaire au fonctionnement d' object-position . La seule différence est que la position par défaut de object-position est différente de celle de background-position .

Quand ne pas utiliser object-fit ou background-size

Si l'élément ou l'image a une hauteur fixe et que background-size: cover ou object-fit: cover lui est appliqué, il y aura un point où l'image sera trop large, perdant ainsi des détails importants qui pourraient affecter la façon dont l'utilisateur perçoit l'image.

Prenons l'exemple suivant dans lequel l'image se voit attribuer une hauteur fixe :

 .card__thumb { height: 220px; }
Un exemple où une image est trop large car elle a une hauteur fixe, et le conteneur de la carte est trop large
L'image affichée à droite est trop large car elle a une hauteur fixe alors que le conteneur de la carte est trop large. ( Grand aperçu )

Si le conteneur de la carte est trop large, cela se traduira par ce que nous voyons à droite (une image trop large). C'est parce que nous ne spécifions pas de rapport d'aspect.

Il n'y a qu'un des deux correctifs pour cela. La première consiste à utiliser le padding hack pour créer un rapport intrinsèque.

 .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 deuxième solution consiste à utiliser la nouvelle propriété CSS aspect-ratio . En l'utilisant, nous pouvons faire ce qui suit :

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

Remarque : J'ai déjà écrit en détail sur la propriété de aspect-ratio au cas où vous voudriez en savoir plus : "Apprenons à propos du rapport d'aspect en CSS".

Cas d'utilisation et exemples

Avatars d'utilisateurs

Un cas d'utilisation parfait pour object-fit: cover est constituée d'avatars d'utilisateurs. Le format d'image autorisé pour un avatar est souvent carré. Placer une image dans un conteneur carré pourrait déformer l'image.

Un avatar utilisateur sans object-fit et avec object-fit : cover
Une comparaison d'un avatar d'utilisateur sans object-fit et avec object-fit: cover . ( Grand aperçu )
 .c-avatar { object-fit: cover; }

Liste des logos

La liste des clients d'une entreprise est importante. Nous utiliserons souvent des logos à cette fin. Parce que les logos auront des tailles différentes, nous avons besoin d'un moyen de les redimensionner sans les déformer.

Heureusement, object-fit: contain est une bonne solution pour cela.

 .logo__img { width: 150px; height: 80px; object-fit: contain; }
Une liste de logos : Airbnb, Domino’s Pizza, Apple Pay, Amazon
Utiliser object-fit: contain peut nous aider à redimensionner les logos des clients sans les déformer. ( Grand aperçu )

Vignette de l'article

C'est un cas d'utilisation très courant. Le conteneur d'une vignette d'article peut ne pas toujours avoir une image avec le même rapport d'aspect. Ce problème devrait être résolu par le système de gestion de contenu (CMS) en premier lieu, mais ce n'est pas toujours le cas.

 .article__thumb { object-fit: cover; }
Vignette de l'article
Ajustement des miniatures d'articles avec un peu d'aide d' object-fit: cover . ( Grand aperçu )

Fond de héros

Dans ce cas d'utilisation, la décision d'utiliser un élément img ou un arrière-plan CSS dépendra des éléments suivants :

  • L'image est-elle importante ? Si CSS est désactivé pour une raison quelconque, voudrions-nous que l'utilisateur voie l'image ?
  • Ou le but de l'image est-il simplement décoratif ?

En fonction de notre réponse, nous pouvons décider quelle fonctionnalité utiliser. Si l'image est importante :

Cas d'utilisation avec un arrière-plan de héros
Supposons que l'image soit importante, car il s'agit d'un site Web lié à l'alimentation. ( Grand aperçu )
 <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; }

Si l'image est décorative , nous pouvons utiliser 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; }

Le CSS est plus court dans ce cas. Assurez-vous que tout texte placé sur l'image est lisible et accessible.

Ajouter un arrière-plan à une image avec object-fit: contain

Saviez-vous que vous pouvez ajouter une couleur de fond à img ? Nous en tirerions profit si nous utilisions également object-fit: contain .

Dans l'exemple ci-dessous, nous avons une grille d'images. Lorsque les proportions de l'image et du conteneur sont différentes, la couleur d'arrière-plan apparaît.

 img { object-fit: contain; background-color: #def4fd; }
Ajouter une couleur de fond à une image avec object-fit: contains
Nous pouvons utiliser object-fit: contain pour ajouter une couleur de fond à une image. ( Grand aperçu )

Élément vidéo

Avez-vous déjà eu besoin d'une video en arrière-plan ? Si tel est le cas, vous vouliez probablement qu'il occupe toute la largeur et la hauteur de son parent.

 .hero { position: relative; background-color: #def4fd; } .hero__video { position: aboslute; left: 0; top: 0; width: 100%; height: 100%; }
Un chiffre où la vidéo ne couvre pas le fond du héros
La valeur object-fit par défaut pour l'élément video est contain . Comme vous pouvez le voir ici, la vidéo ne couvre pas l'arrière-plan du héros, même s'il a position: absolute , la width: 100% et la height: 100% . ( Grand aperçu )

Pour qu'il couvre entièrement la largeur et la hauteur de son parent, nous devons remplacer la valeur object-fit par défaut :

 .hero__video { /* other styles */ object-fit: cover; }
Une figure où la vidéo couvre toute la largeur et la hauteur de son parent.
Maintenant, la vidéo couvre toute la largeur et la hauteur de son parent. ( Grand aperçu )

Conclusion

Comme nous l'avons vu, l' object-fit et background-size sont très utiles pour gérer différents formats d'image. Nous n'aurons pas toujours le contrôle sur la définition des dimensions parfaites pour chaque image, et c'est là que ces deux fonctionnalités CSS brillent.

Un rappel amical sur les implications pour l'accessibilité du choix entre un élément img et un arrière-plan CSS : si l'image est purement décorative, optez pour un arrière-plan CSS. Sinon, un img est plus approprié.

J'espère que vous avez trouvé cet article utile. Merci pour la lecture.